This is my first time deploying a FastAPI + gunicorn web application with NGINX and the struggle is real.
My web app is running on an AWS EC2 machine using Docker.
What I've done so far:
- register a domain with godaddy - let's call the domain example.club
- Setup a DNS A record pointing to my server's public IP Address (via godaddy DNS management page).
- created a site-conf.conf file and put it into /etc/nginx/sites-available. The file has the following configuration:
server {
listen 80;
listen 443;
server_name example.club;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Linked my .conf file to /etc/nginx/sites-enabled with the following command:
sudo ln -s /etc/nginx/sites-available/site-conf.conf /etc/nginx/sites-enabled/site-conf.confRestarted my NGINX service using the command:
sudo systemctl restart nginx. When looking at the journalctl logs, everything looks normal:
-- Unit nginx.service has begun starting up.
Nov 14 19:14:42 <server-address> nginx[16558]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Nov 14 19:14:42 <server-address> nginx[16558]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Nov 14 19:14:42 <server-address> systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Nov 14 19:14:42 <server-address> sudo[16537]: pam_unix(sudo:session): session closed for user root
Nov 14 19:14:42 <server-address> systemd[1]: Started The nginx HTTP and reverse proxy server.
-- Subject: Unit nginx.service has finished start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit nginx.service has finished starting up.
--
-- The start-up result is done.
At this point, when opening up http://example.club I can see a "Thanks for using Amazon Linux" page.
To me, this confirms that my domain correctly points to my server's IP address + NGINX is setup correctly.
- Now, all I want is to "connect" my NGINX proxy with my dockerized GUNICORN + FastAPI application (in order to expose my APIs to the world).
To do this, I use the following Dockerfile:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
WORKDIR /app
COPY . /app
# add files to Docker environment
...
# run app
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["gunicorn", "-b", "127.0.0.1:8080", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
- Finally, I build my image (
sudo docker build -t myimage .) and run the container:
sudo docker run --name mycontainer -e PYTHONUNBUFFERED=1 -p 8080:8080 -d myimage
while making sure I publish port 8080 correctly.
The container's logs look normal:
[2020-11-14 17:32:34 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2020-11-14 17:32:34 +0000] [1] [INFO] Listening at: http://127.0.0.1:8080 (1)
[2020-11-14 17:32:34 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-11-14 17:32:34 +0000] [8] [INFO] Booting worker with pid: 8
[2020-11-14 17:32:34 +0000] [8] [INFO] Started server process [8]
2020-11-14 17:32:34,783 Started server process [8]
[2020-11-14 17:32:34 +0000] [8] [INFO] Waiting for application startup.
2020-11-14 17:32:34,783 Waiting for application startup.
[2020-11-14 17:32:34 +0000] [8] [INFO] Application startup complete.
2020-11-14 17:32:34,784 Application startup complete.
I should also mention that I opened port 8080 for TCP from any IP address by updating inbound rules in the EC2 machine's security group.
Unfortunately, when I try to access one of my APIs (http://example.club/<some-route-defined-with-FastAPI>) I get the NGINX default 404 page.
What am I doing wrong? Why isn't the NGINX proxy recognizing my routes?