排查Docker容器Flask应用搭配Nginx反向代理的503服务不可用问题
问题:Docker+Gunicorn+Nginx部署Flask应用出现503错误
问题概述
在虚拟机上用Docker、Gunicorn和Nginx部署Flask应用,目标是把https://myapp.virtual_machine.org的请求转发到localhost:5000,但访问时返回503 Service Unavailable错误。
Docker化Flask应用配置
已在虚拟机创建两个容器,本地可通过http://127.0.0.1:5000访问应用。
app.py代码
from app import app if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)
docker-compose.yml配置
version: '3' services: pgsql: image: postgres:12.11 #restart: always environment: POSTGRES_PASSWORD: pwd POSTGRES_USER: usr POSTGRES_DB: users volumes: - users-vol:/var/lib/postgresql/data ports: - 5432:5433 myapp: build: context: . dockerfile: Dockerfile depends_on: - pgsql ports: - 5000:5000 image: myapp/myapp volumes: users-vol:
Dockerfile内容
# 使用预配置的Python镜像 FROM python:3.9 # 安装依赖 COPY requirements.txt /var/www/app/requirements.txt WORKDIR /var/www/app # 设置环境变量 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # 更新包并安装依赖 RUN pip install --upgrade pip \ && pip install gunicorn \ && pip install --no-cache-dir -r requirements.txt \ && rm -rf /var/cache/apk/* # 将Flask应用代码复制到容器中 COPY . /var/www/app # 设置Flask环境变量 ENV FLASK_APP = app.py ENV FLASK_DEBUG=true ENV FLASK_ENV=deployement EXPOSE 5000 CMD ["sh", "-c", "sleep 5 && gunicorn --workers 3 --bind 127.0.0.1:5000 app:app"]
docker-compose启动日志
pgsql_1 | 2023-05-20 09:04:21.204 UTC [26] LOG: redo starts at 0/2B9C4F8 pgsql_1 | 2023-05-20 09:04:21.204 UTC [26] LOG: invalid record length at 0/2B9C5E0: wanted 24, got 0 pgsql_1 | 2023-05-20 09:04:21.204 UTC [26] LOG: redo done at 0/2B9C5A8 pgsql_1 | 2023-05-20 09:04:21.581 UTC [1] LOG: database system is ready to accept connections givemeasign_1 | [2023-05-20 09:04:27 +0000] [8] [INFO] Starting gunicorn 20.1.0 givemeasign_1 | [2023-05-20 09:04:27 +0000] [8] [INFO] Listening at: http://127.0.0.1:5000 (8) givemeasign_1 | [2023-05-20 09:04:27 +0000] [8] [INFO] Using worker: sync givemeasign_1 | [2023-05-20 09:04:27 +0000] [9] [INFO] Booting worker with pid: 9 givemeasign_1 | [2023-05-20 09:04:27 +0000] [10] [INFO] Booting worker with pid: 10 givemeasign_1 | [2023-05-20 09:04:27 +0000] [11] [INFO] Booting worker with pid: 11
Nginx配置
虚拟机IP为xx.xx.xx.xx,域名为myapp.virtual_machine.org,已配置HTTPS反向代理,证书文件存于/etc/nginx/nginx_cert目录(包含ca.crt、nginx-selfsigned.crt、nginx-selfsigned.key,证书无问题),站点配置文件位于/etc/nginx/sites-enabled和/etc/nginx/sites-available目录:
server { listen 443 ssl; server_name myapp.virtual_machine.org; ssl_certificate /etc/nginx/nginx_cert/nginx-selfsigned.crt; ssl_certificate_key /etc/nginx/nginx_cert/nginx-selfsigned.key; ssl_client_certificate /etc/nginx/nginx_cert/ca.crt; ssl_verify_client optional; location / { if ($ssl_client_verify != SUCCESS) { return 403; } root /home/student/myapp/backend; proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X_Forwarded-For $proxy_add_x_forwarded_for; } }
解决方案
1. 修复Gunicorn绑定地址
从启动日志可见,Gunicorn绑定的是容器内部的127.0.0.1:5000,仅容器自身能访问,导致宿主机无法通过端口映射访问服务。修改Dockerfile中的启动命令,将绑定地址改为0.0.0.0:5000:
CMD ["sh", "-c", "sleep 5 && gunicorn --workers 3 --bind 0.0.0.0:5000 app:app"]
2. 修正Nginx配置问题
- 移除不必要的
root指令:反向代理场景下无需指定本地目录 - 修正请求头格式:
X_Forwarded-For改为标准连字符格式X-Forwarded-For - 暂时注释客户端证书验证逻辑,先确保反向代理正常(后续按需恢复)
修改后的Nginx配置:
server { listen 443 ssl; server_name myapp.virtual_machine.org; ssl_certificate /etc/nginx/nginx_cert/nginx-selfsigned.crt; ssl_certificate_key /etc/nginx/nginx_cert/nginx-selfsigned.key; # ssl_client_certificate /etc/nginx/nginx_cert/ca.crt; # ssl_verify_client optional; location / { # if ($ssl_client_verify != SUCCESS) { # return 403; # } proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
3. 验证连通性与重启服务
- 重新构建并启动容器:
docker-compose down docker-compose up --build -d
- 验证Nginx配置并重启服务:
nginx -t systemctl restart nginx
- 在宿主机执行
curl http://127.0.0.1:5000,确认能收到Flask应用响应
内容的提问来源于stack exchange,提问作者INNO BOY
相关产品推荐
相关产品推荐

