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 问题如何解决?

12 回复

nginx 的 localhost:5000 改成 webapp:5000


502 Bad Gateway 通常意味着 Nginx 无法连接到上游服务(这里是 Flask)。在 Docker Compose 环境下,最常见的原因是网络配置或服务健康检查问题。

核心检查点:

  1. Nginx 配置中的 upstream 地址:必须使用 Docker Compose 的服务名,而不是 localhost127.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;
    }
    
  2. 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
    
  3. 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 参数,现在似乎说得通了。

抱歉,上一条回复是错误的,虽然 nginx 会报警告,:
nginx: [emerg] host not found in upstream “webapp” in /etc/nginx/conf.d/nginx.conf:10

对 docker-compose network 配置没有深入了解,这里得指定 docker-compose 网络名,具体细节请参考:
https://docs.docker.com/compose/networking/

回到顶部