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

