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

Docker化Django应用无法通过域名访问?Traefik配置求助

问题描述

问题现象

在Windows机器的浏览器中,可通过localhost:5000、192.168.1.100:5000访问Docker化Django的默认页面,但无法通过域名example.com访问;同一机器可通过monitor.example.com正常访问Traefik仪表盘,说明公网到内部Docker容器的路由通路正常。

实验室环境配置

  • 借助Cloudflare将example.com指向公网IP;
  • 本地边缘路由器将80、443端口转发至Docker主服务器(x.x.x.165);
  • Docker主服务器运行Docker化Traefik实例;
  • Windows系统的Docker Desktop运行简易Django应用(x.x.x.100);
  • 使用Cloudflare源证书而非Let's Encrypt。

相关配置文件

Traefik docker-compose.yml

networks:
  mynet:
    external: true

services:
  traefik:
    image: docker.io/library/traefik:2.11.2
    container_name: traefik
    ports:
      - 80:80
      - 443:443
      # -- (Optional) Enable Dashboard, don't do in production
      - 8080:8080
    environment:
      - CF_DNS_API_TOKEN=[cloudflare token]
      - TZ=[local timezone]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config/traefik.yml:/etc/traefik/traefik.yml:ro    # For the static configuration 
      - ./config/config.yml:/etc/traefik/config.yml:ro      # For any dynamic configuration you add
      - ./certs:/certs:ro                               # location for the certs
      - ./logs:/var/log/traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:[password]"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.entrypoints=web"
      - "traefik.http.routers.traefik.rule=Host(`monitor.example.com`)"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=websecure"
      - "traefik.http.routers.traefik-secure.rule=Host(`monitor.example.com`)"
      - "traefik.http.routers.traefik-secure.service=api@internal"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
    networks:
      - mynet

Traefik config.yml(仅Django相关路由)

tls:
  certificates:
    - certFile: /certs/[origin cert].crt
      keyFile: /certs/[origin cert].key
http:
  routers:
    django:
      rule: "Host(`example.com`) || Host(`www.example.com`)"
      entryPoints:
        - "web"
      service: django

  services:
    django:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:5000"

Traefik.yml

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
 level: INFO

api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: :80
    # http:                # commenting this out to just try getting http working first
    #   redirections:
    #     entryPoint:
    #       to: websecure
    #       scheme: https     
  websecure:
    address: :443

serversTransport:
  insecureSkipVerify: true

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: mynet
  file:
    filename: /etc/traefik/config.yml
    watch: true

Django docker-compose.yml

volumes:
  production_postgres_data: {}
  production_postgres_data_backups: {}
  production_django_media: {}

networks: 
  mynet:
    external: true

services:
  django:
    build:
      context: .
      dockerfile: ./compose/production/django/Dockerfile
    image: project_production_django
    container_name: project_production_django
    volumes:
      - production_django_media:/app/project/media
    depends_on:
      - postgres
    env_file:
      - ./.envs/.production/.django
      - ./.envs/.production/.postgres
    networks:
      - mynet
    ports:
      - 5000:5000
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: project_production_postgres
    container_name: project_production_postgres
    volumes:
      - production_postgres_data:/var/lib/postgresql/data
      - production_postgres_data_backups:/backups
    env_file:
      - ./.envs/.production/.postgres
    networks:
      - mynet

Django配置

ALLOWED_HOSTS = ["localhost", "127.0.0.1", "192.168.1.100", ".example.com",]

问题排查与修复建议

结合现有配置和现象,以下是可能的遗漏或配置错误点:

1. 缺少HTTPS路由配置

当前Django仅配置了80端口的web路由,但Cloudflare通常强制HTTPS访问,且你的Traefik仪表盘已配置HTTPS跳转逻辑。需要补充443端口的websecure路由并启用TLS:

修改Traefik config.yml,补充HTTPS路由:

http:
  routers:
    django:
      rule: "Host(`example.com`) || Host(`www.example.com`)"
      entryPoints:
        - "web"
      service: django
      # 复用已有的HTTP转HTTPS中间件
      middlewares:
        - traefik-https-redirect
    # 新增HTTPS路由
    django-secure:
      rule: "Host(`example.com`) || Host(`www.example.com`)"
      entryPoints:
        - "websecure"
      service: django
      tls: true

  services:
    django:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:5000"

2. Django信任代理配置缺失

Traefik作为反向代理会向Django传递X-Forwarded-*头,但Django默认不信任这些头,会导致请求来源验证失败。需要在Django的settings.py中添加:

USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# 添加Traefik所在服务器IP到信任列表
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "192.168.1.100", ".example.com", "x.x.x.165"]

3. 跨服务器网络连通性验证

确保Docker主服务器(x.x.x.165)能直接访问Windows机器的192.168.1.100:5000,因为Traefik运行在该服务器上,需要直接连接Django容器端口。在Docker主服务器执行测试命令:

curl http://192.168.1.100:5000

如果无法访问,检查Windows防火墙是否允许来自x.x.x.165的请求访问5000端口。

4. Cloudflare SSL/TLS模式配置

使用Cloudflare源证书时,需将Cloudflare的SSL/TLS模式设置为**"完全"或"严格"**,确保Cloudflare与Traefik之间的连接使用HTTPS,避免证书不匹配或请求异常。

5. Traefik日志排查

将Traefik日志级别改为DEBUG,查看请求路由细节:
修改Traefik.yml中的日志配置:

log:
 level: DEBUG

重启Traefik后,查看./logs/目录下的日志,检查example.com请求是否被正确路由,是否存在连接错误、证书错误等信息。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:45:00