Flask + Nginx + Docker-compose 遇到 502 Bad Gateway 问题如何解决?
请教一下,我用 docker-compose 部署 Flask + Nginx + Docker-compose + gunicorn 应用,本地访问 0.0.0.0:5000 可以访问,访问 0.0.0.0:80 显示 502 bad gate,但 0.0.0.0:80/static/… 静态文件能成功访问,不知道是配置文件哪个地方配错,有没有什么建议?非常感谢
docker-compose.yml
version: '3'
services:
webapp:
build: .
# command: bash ./start_server.sh
# env_file: .env
volumes:
- ./webapp:/iodock/
ports:
- “5000:5000” # web 容器内的 5000 端口映射到主机的 5000 端口
depends_on:
- nginx
nginx:
restart: always
image: nginx:stable
volumes:
- ./webconf/nginx/conf.d/:/etc/nginx/conf.d/
- ./webconf/nginx/log/:/var/log/nginx/
- ./webconf/nginx/cert/:/opt/cert/
- ./webapp/app/static/:/opt/static/
ports:
- “80:80”
- “443:443”
Dockerfile
# --------------------------
# Docker file
# --------------------------
FROM python:3.6
Set system language
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
install python requirement
COPY ./webapp/requirements.txt /tmp/requirements.txt
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip
RUN pip3 install --no-cache-dir gunicorn
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r /tmp/requirements.txt
Create root folder docker_web_app
COPY ./webapp /docker_web_app/iodock/
WORKDIR /iodock/
ENV PORT 5000
EXPOSE 5000
CMD ["/usr/local/bin/gunicorn", “-w”, “2”, “-b”, “:5000”, “manage:app”]
nginx.conf
server {
listen 80;
server_name localhost; # 公网地址
access_log /var/log/nginx/nginx_access.log;
error_log /var/log/nginx/nginx_error.log;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /opt/static;
proxy_set_header Host $host;
# proxy_cache mycache;
# expires 30d;
}
}
nginx_error.log
2019/04/21 14:36:18 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "0.0.0.0"
2019/04/21 14:36:18 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "0.0.0.0"
2019/04/21 14:36:19 [error] 7#7: *1 no live upstreams while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://localhost/favicon.ico", host: "0.0.0.0", referrer: "http://0.0.0.0/"
Flask + Nginx + Docker-compose 遇到 502 Bad Gateway 问题如何解决?
nginx 的 localhost:5000 改成 webapp:5000
502 Bad Gateway 通常意味着 Nginx 无法连接到上游服务(这里是 Flask)。在 Docker Compose 环境下,最常见的原因是网络配置或服务健康检查问题。
核心检查点:
-
Nginx 配置中的 upstream 地址:必须使用 Docker Compose 的服务名,而不是
localhost或127.0.0.1。# 正确示例 location / { proxy_pass http://flask_app:5000; # 'flask_app' 是 compose 文件里的服务名 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } -
Flask 应用的监听地址:在 Docker 容器内,Flask 必须监听
0.0.0.0。# app.py 或启动脚本 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) # 关键!或者通过环境变量设置:
# docker-compose.yml 片段 services: flask_app: ... environment: - FLASK_RUN_HOST=0.0.0.0 - FLASK_RUN_PORT=5000 -
Docker Compose 网络:确保服务在同一个默认网络或自定义网络中。
一个最小可工作的 docker-compose.yml 示例:
version: '3.8'
services:
flask_app:
build: ./flask_app # 你的 Flask 应用 Dockerfile 路径
expose:
- "5000"
# 或者使用 ports 映射到主机用于直接测试
# ports:
# - "5000:5000"
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- flask_app
快速诊断命令:
# 1. 查看 Flask 容器日志,确认是否启动成功并在监听 0.0.0.0:5000
docker-compose logs flask_app
# 2. 进入 Nginx 容器,测试是否能连接到 Flask 服务
docker-compose exec nginx sh
# 在容器内执行:
curl http://flask_app:5000/health # 或你的某个端点
一句话总结:检查 Nginx 配置中的服务名和 Flask 是否监听 0.0.0.0。
非常感谢!成功了,原来是要指明容器对象
顺便把 flask 里面的
- “5000:5000” # web 容器内的 5000 端口映射到主机的 5000 端口
这一样删了吧,都通过 nginx 访问了, 就没有必要暴露出原始端口了
有道理,我试试看,谢谢!
支持一下!
正好顺便请教下,我用 portainer 部署了个 gitlab-ce,通过 cdn 访问总是间隔性有 422 出错提示:
下面是 nginx 的的配置,是否 proxy_pass http://127.0.0.1:8880; 这个我也要改为 docker 的容器对象名才可?
location /
{
location ~ .*.(php|jsp|cgi|asp|aspx|flv|swf|xml)?$
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_pass http://127.0.0.1:8880;
}
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
以下为 docker ps:
[rootback ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed82dc089c7e gitlab/gitlab-ce:latest “/assets/wrapper” 3 weeks ago Up 9 days (healthy) 0.0.0.0:8222->22/tcp, 0.0.0.0:8880->80/tcp, 0.0.0.0:8443->443/tcp Gitlab-CE
807229f4387e portainer/portainer “/portainer” 3 weeks ago Up 9 days 0.0.0.0:9000->9000/tcp
你可以试试看,但按我的了解,如果是配置错了应该是必定不工作
容器对象我是写 CONTAINER ID:ed82dc089c7e 好还是 NAMES:Gitlab-CE 好呢
囧,不太懂,其实我是搞嵌入式单片机的。。。
更新一下贴子,修改为webapp:5000不是正确的解法,nginx 报错,猜测是因为 nginx 无法识别 webapp 所以变成类似:5000? 所以我试了一下0.0.0.0:5000,可以成功运行。之前一直纳闷为什么 nginx 可以识别 docker-compose.yml 中的 webapp 参数,现在似乎说得通了。


