Traefik配置后始终返回404,容器化Go应用无法访问
问题描述
尝试为容器化Go应用配置Traefik,但所有端点访问均返回404。Go应用运行在my-service容器内,监听80端口,无Traefik时可正常运行,问题出在Traefik配置上。
docker-compose.yml
version: '3' services: my-service: container_name: my-service-backend labels: - traefik.http.routers.my-service.rule=Host(`my-service.docker.localhost`) - traefik.http.services.my-service.loadbalancer.server.port=80 - traefik.port=80 - traefik.enable=true build: context: . dockerfile: Dockerfile-${ENV} restart: always expose: - 80 deploy: mode: replicated replicas: 1 environment: USER: ${DB_USER} PASSWORD: ${DB_PASSWORD} DB: ${DB_NAME} HOST: ${DB_HOST} PORT: ${DB_PORT} LISTEN_PORT: ${LISTEN_PORT} ENV: ${ENV} networks: - backend traefik: image: traefik:v3.0 # Enables the web UI and tells Traefik to listen to docker. DISABLE IN PRODUCTION command: --api.insecure=true --providers.docker ports: # The HTTP port - "80:80" # The Web UI (enabled by --api.insecure=true) - "8080:8080" volumes: # So that Traefik can listen to the Docker events - /var/run/docker.sock:/var/run/docker.sock - ./traefik.yaml:/etc/traefik/traefik.yaml networks: - backend networks: backend: name: backend
traefik.yaml
accessLog: {} log: {} providers: docker: exposedByDefault: false network: backend api: dashboard: true insecure: true debug: true entryPoints: web: address: ":80" websecure: address: ":443"
执行curl -GET localhost:80/ping和curl -GET my-service.docker.localhost/ping均返回404,Traefik日志显示:
192.168.65.1 - - [12/Jun/2024:03:51:12 +0000] "GET /ping HTTP/1.1" 404 19 "-" "-" 1 "my-service@docker" "http://172.18.0.3:80" 18ms
问题分析与解决方案
核心问题
- 命令行与配置文件参数冲突:Traefik服务同时通过command和配置文件重复定义了API和Docker Provider参数,导致配置逻辑混乱。
- 路由未绑定EntryPoint:Traefik v3要求路由必须明确关联到指定的EntryPoint,否则请求无法匹配到对应路由。
- 冗余旧版本标签:
traefik.port是Traefik v1的废弃标签,与v3的服务端口配置重复,易引发混淆。
修正步骤
1. 修复Traefik服务的启动命令
删除command中与配置文件重复的参数,改用配置文件统一管理:
traefik: image: traefik:v3.0 command: --configfile=/etc/traefik/traefik.yaml ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.yaml:/etc/traefik/traefik.yaml networks: - backend
2. 调整my-service的Traefik标签
添加EntryPoint绑定,删除废弃的traefik.port标签:
my-service: container_name: my-service-backend labels: - traefik.http.routers.my-service.rule=Host(`my-service.docker.localhost`) - traefik.http.routers.my-service.entrypoints=web # 绑定到web入口点 - traefik.http.services.my-service.loadbalancer.server.port=80 - traefik.enable=true # 其余配置保持不变
3. 验证本地域名解析
确保本地hosts文件添加以下映射(避免域名解析失败):
127.0.0.1 my-service.docker.localhost
验证操作
重启容器集群:
docker-compose down && docker-compose up -d
执行以下命令验证:
curl my-service.docker.localhost/ping
额外说明
curl localhost:80/ping返回404是预期行为:路由规则仅匹配my-service.docker.localhost主机名,直接用localhost访问不匹配任何路由。- 日志显示请求已转发到应用容器,说明Traefik已识别服务,修正后即可正常转发请求。
内容的提问来源于stack exchange,提问作者yulia
相关产品推荐
相关产品推荐

