You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Traefik2作为Nginx反向代理部署Django生产环境遇Bad Gateway错误

Django + Nginx + Traefik2 部署Bad Gateway问题排查

问题背景

已完成一个基础功能的Django应用,本地运行正常,计划部署到已有Traefik2作为反向代理(配置Let's Encrypt证书)的生产服务器,希望保留Nginx处理静态文件的架构,让Traefik作为Nginx的前置代理。但使用当前配置后浏览器返回"Bad Gateway"错误;若将Traefik标签配置到web服务,Django可正常运行,但无法获取静态文件。

当前配置文件

docker-compose.pro.yml

version: "3.9"

# docker-compose for production
# It is important that the .env.prod is used.
# For this, docker-compose must always be executed
# with the command docker-compose -f docker-compose.pro.yml --env-file .env.prod.

services:
  web:
    build:
      context: .
      dockerfile: ./compose/Dockerfile
    restart: always
    command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
    env_file:
      - ./.env.prod
    expose:
      - 8000
    volumes:
      - static_volume:/code/staticfiles
      - media_volume:/code/mediafiles
    depends_on:
      - redis
      - db
    networks:
      - pjnet

  db:
    image: postgres:15
    restart: always
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=${DB_USERNAME}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}
    networks:
      - pjnet

  redis:
    image: redis:7
    networks:
      - pjnet

  celery:
    build:
      context: .
      dockerfile: ./compose/Dockerfile
    restart: always
    command: celery -A project worker -l info
    volumes:
      - .:/code
    env_file:
      - ./.env.prod
    depends_on:
      - db
      - redis
      - web
    networks:
      - pjnet

  nginx:
    build: ./compose/nginx
    restart: always
    ports:
      - ${NGINX_PORT}:80
    volumes:
      - static_volume:/code/staticfiles
      - media_volume:/code/mediafiles
    labels:
      - traefik.enable=true
      - traefik.http.routers.blogng.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogng.entrypoints=http
      - traefik.http.routers.blogng.middlewares=https-redirect

      - traefik.http.routers.blogngsec.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogngsec.entrypoints=https
      - traefik.http.routers.blogngsec.tls.certresolver=le
      - traefik.http.routers.blogngsec.service=blogngsec
      - traefik.http.services.blogngsec.loadbalancer.server.port=${NGINX_PORT}
    depends_on:
      - web
    networks:
      - pjnet
      - traefik-net

volumes:
  postgres_data:
  static_volume:
  media_volume:

networks:
  traefik-net:
    external: true
  pjnet:

nginx.conf

upstream web_app {
    server web:8000;
}

server {

    listen 80;

    location /static/ {
        alias /code/staticfiles/;
    }

    location /media/ {
        alias /code/mediafiles/;
    }

    location / {
        proxy_pass http://web_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

}

问题原因及修复方案

核心错误:Traefik服务端口配置错误

Traefik与Nginx在同一个traefik-net Docker网络中,容器间通信应使用容器内部的端口,而非宿主机的端口映射值。当前配置的traefik.http.services.blogngsec.loadbalancer.server.port=${NGINX_PORT}指向宿主机端口,Traefik无法通过该端口访问到Nginx容器,导致Bad Gateway。

修复步骤

  1. 修改Nginx服务的Traefik标签,将服务端口改为Nginx容器内部监听的80端口:

    labels:
      - traefik.enable=true
      - traefik.http.routers.blogng.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogng.entrypoints=http
      - traefik.http.routers.blogng.middlewares=https-redirect
    
      - traefik.http.routers.blogngsec.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogngsec.entrypoints=https
      - traefik.http.routers.blogngsec.tls.certresolver=le
      - traefik.http.routers.blogngsec.service=blogngsec
      - traefik.http.services.blogngsec.loadbalancer.server.port=80  # 改为容器内部端口80
    
  2. 可选优化:移除Nginx服务的ports配置
    由于Traefik已作为前置代理处理外部请求,无需将Nginx端口暴露给宿主机,可删除ports: - ${NGINX_PORT}:80这一行,减少不必要的端口暴露。

额外检查点

  • 确认Nginx容器正常启动:执行docker-compose -f docker-compose.pro.yml --env-file .env.prod logs nginx查看日志,排查是否有启动报错。
  • 确认静态文件已正确收集:在Django容器中运行python manage.py collectstatic --noinput,确保静态文件已同步到static_volume卷中。
  • 检查Django生产配置:
    • .env.prod中ALLOWED_HOSTS需包含blog.project.com
    • CSRF_TRUSTED_ORIGINS需添加https://blog.project.com
    • DEBUG需设为False

内容的提问来源于stack exchange,提问作者WillHoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:29:59