让 NGINX 与 gunicorn 网络应用程序一起工作
getting NGINX to work with gunicorn web application
这是我第一次使用 NGINX 部署 FastAPI + gunicorn web 应用程序,这是真实的。
我的 Web 应用程序 运行ning 在 AWS EC2 机器上使用 Docker.
到目前为止我做了什么:
- 在 godaddy 注册一个域 - 让我们称该域为 example.club
- 设置指向我服务器的 public IP 地址的 DNS A 记录(通过 godaddy DNS 管理页面)。
- 创建了一个 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;
}
}
使用以下命令将我的 .conf 文件链接到 /etc/nginx/sites-enabled:
sudo ln -s /etc/nginx/sites-available/site-conf.conf /etc/nginx/sites-enabled/site-conf.conf
使用以下命令重新启动了我的 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可以看到“感谢使用亚马逊Linux”页面。
对我来说,这确认我的域正确指向我服务器的 IP 地址 + NGINX 设置正确。
- 现在,我只想将我的 NGINX 代理与我的 dockerized GUNICORN + FastAPI 应用程序“连接”(以便向世界公开我的 API)。
为此,我使用以下命令Docker文件:
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"]
- 最后,我构建了我的镜像 (
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>) I get the NGINX default 404 page.
我做错了什么?为什么 NGINX 代理不能识别我的路由?
尝试删除 /etc/nginx/sites-enabled/ 中的默认配置文件(应该只称为默认)和 /etc/nginx/sites-available/ 中的默认配置文件并在 [=12= 中的当前配置中添加 default_server
]行。
server {
listen 80 default_server;
listen 443;
server_name example.club;
...
}
为了将来参考,我最后做的是绑定到“0.0.0.0”:
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", "0.0.0.0:8080", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
我还稍微修改了我的 NGINX site-conf.conf(删除 listens):
server {
server_name example.*;
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;
}
}
最后,我安装了python-certbot-nginx:
sudo yum install python-certbot-nginx
和运行它与:
sudo certbot --nginx -d example.club -d www.example.club
此设置允许我使用 HTTPS 连接到我的域,但我还有一个问题:我 仍然可以通过显式访问来使用 HTTP 访问我的网络服务器对于端口 8080 (curl http://example.club:8080/<api-endpoint>
).
为了解决这个问题,我转到 AWS 网站的安全组菜单,只允许从我机器的 IP 访问端口 8080:
screenshot
这是我第一次使用 NGINX 部署 FastAPI + gunicorn web 应用程序,这是真实的。
我的 Web 应用程序 运行ning 在 AWS EC2 机器上使用 Docker.
到目前为止我做了什么:
- 在 godaddy 注册一个域 - 让我们称该域为 example.club
- 设置指向我服务器的 public IP 地址的 DNS A 记录(通过 godaddy DNS 管理页面)。
- 创建了一个 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;
}
}
使用以下命令将我的 .conf 文件链接到 /etc/nginx/sites-enabled:
sudo ln -s /etc/nginx/sites-available/site-conf.conf /etc/nginx/sites-enabled/site-conf.conf
使用以下命令重新启动了我的 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可以看到“感谢使用亚马逊Linux”页面。
对我来说,这确认我的域正确指向我服务器的 IP 地址 + NGINX 设置正确。
- 现在,我只想将我的 NGINX 代理与我的 dockerized GUNICORN + FastAPI 应用程序“连接”(以便向世界公开我的 API)。
为此,我使用以下命令Docker文件:
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"]
- 最后,我构建了我的镜像 (
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>) I get the NGINX default 404 page.
我做错了什么?为什么 NGINX 代理不能识别我的路由?
尝试删除 /etc/nginx/sites-enabled/ 中的默认配置文件(应该只称为默认)和 /etc/nginx/sites-available/ 中的默认配置文件并在 [=12= 中的当前配置中添加 default_server
]行。
server {
listen 80 default_server;
listen 443;
server_name example.club;
...
}
为了将来参考,我最后做的是绑定到“0.0.0.0”:
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", "0.0.0.0:8080", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
我还稍微修改了我的 NGINX site-conf.conf(删除 listens):
server {
server_name example.*;
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;
}
}
最后,我安装了python-certbot-nginx:
sudo yum install python-certbot-nginx
和运行它与:
sudo certbot --nginx -d example.club -d www.example.club
此设置允许我使用 HTTPS 连接到我的域,但我还有一个问题:我 仍然可以通过显式访问来使用 HTTP 访问我的网络服务器对于端口 8080 (curl http://example.club:8080/<api-endpoint>
).
为了解决这个问题,我转到 AWS 网站的安全组菜单,只允许从我机器的 IP 访问端口 8080:
screenshot