首页 > 解决方案 > 让 NGINX 与 gunicorn Web 应用程序一起工作

问题描述


这是我第一次使用 NGINX 部署 FastAPI + gunicorn Web 应用程序,而斗争是真实的。

我的 Web 应用程序正在使用 Docker 的 AWS EC2 机器上运行。
到目前为止我所做的:
  1. 向godaddy注册一个域- 让我们调用域example.club
  2. 设置指向我服务器公共 IP 地址的 DNS A 记录(通过 godaddy DNS 管理页面)。
  3. 创建了一个site-conf.conf文件并将其放入/etc/nginx/sites-available。该文件具有以下配置:
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;
    }
}
  1. 使用以下命令将 我的.conf文件链接到/etc/nginx/sites-enabled :sudo ln -s /etc/nginx/sites-available/site-conf.conf /etc/nginx/sites-enabled/site-conf.conf

  2. 使用命令重新启动我的 NGINX 服务:sudo systemctl restart nginx. 查看 journalctl 日志时,一切看起来都很正常:

-- 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.

此时,打开http://example.club时,我可以看到“感谢使用 Amazon Linux”页面
对我来说,这证实了我的域正确地指向了我的服务器的 IP 地址 + NGINX 设置正确。

  1. 现在,我想要的只是将我的 NGINX 代理与我的 dockerized GUNICORN + FastAPI 应用程序“连接”起来(以便向世界公开我的 API)。
    为此,我使用以下 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"]
  1. 最后,我构建我的图像 ( sudo docker build -t myimage .) 并运行容器:
sudo docker run --name mycontainer -e PYTHONUNBUFFERED=1 -p 8080:8080 -d myimage

同时确保我正确发布端口 8080。
容器的日志看起来很正常:

[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.

我还应该提到,通过更新 EC2 机器安全组中的入站规则,我从任何 IP 地址为 TCP 开放了端口 8080。

不幸的是,当我尝试访问我的一个 API(http://example.club/ <some-route-defined-with-FastAPI>)时,我得到了NGINX 默认 404 页面

我究竟做错了什么?为什么 NGINX 代理不能识别我的路由?

标签: dockernginxamazon-ec2gunicornfastapi

解决方案


尝试删除 /etc/nginx/sites-enabled/ (应该称为默认)和 /etc/nginx/sites-available/ 中的默认配置文件,并在该行中添加default_server您当前的配置。listen 80

server {
    listen 80 default_server;
    listen 443;
    server_name example.club;
    ...
}

推荐阅读