用Docker启动Traefik并挂载/var/run/docker.sock,配合正确traefik.http.routers和服务标签、同Docker网络及健康检查,即可自动发现Golang微服务。

直接用 Docker 启动 Traefik 并让它自动发现你的 Golang 微服务容器,是最简单、最可靠的方式。手动写配置文件或在 Go 代码里嵌入 Traefik 不仅没必要,还会绕开它的核心优势——动态服务发现。
traefik 启动时必须挂载 /var/run/docker.sock
这是 Traefik 实时监听容器启停事件的唯一途径。不挂载它,--providers.docker=true 就是摆设,所有 traefik.http.routers.xxx 标签都会被忽略。
- Linux/macOS 下路径固定为
/var/run/docker.sock;Windows WSL2 也适用该路径 - Docker Desktop for Mac/Windows 默认已支持该挂载,但需确认 Docker 守护进程正在运行
- 如果用 rootless Docker,路径可能是
$XDG_RUNTIME_DIR/docker.sock,需显式指定 - 权限错误常见于 SELinux 或 AppArmor 启用环境,可临时用
sudo setenforce 0验证是否为此类问题
Golang 服务容器必须打上正确的 traefik 标签
Traefik v3(当前稳定版)只认 traefik.http.routers.xxx 和 traefik.http.services.xxx 这类结构化标签,旧版的 traefik.frontend.rule 已完全失效。
- 最低必要标签组合:
traefik.http.routers.myapp.rule=Host(`app.local`)+traefik.http.routers.myapp.service=myapp+traefik.http.services.myapp.loadbalancer.server.port=8080 - 端口必须与 Golang 服务实际监听端口一致;若服务监听
0.0.0.0:3000,这里就得写3000,不是容器暴露的EXPOSE端口 - 所有标签必须加在
docker run命令中,或docker-compose.yml的labels:下,不能写在 Go 代码里 - 多个路由规则可用逗号拼接,如
Host(`api.example.com`) || PathPrefix(`/v1`)
traefik 与 Golang 服务必须在同一个 Docker 网络
Traefik 默认只能访问同网络内的容器 IP。跨网络或默认 bridge 网络会导致“connection refused”或 502 错误,且日志里几乎不报错。
立即学习“go语言免费学习笔记(深入)”;
- 启动 Traefik 时显式创建并加入网络:
docker network create traefik-net,然后在docker run或docker-compose.yml中指定--network traefik-net - Golang 服务容器也必须加入同一网络,否则 Traefik 解析出的后端地址是
172.x.x.x,但根本连不通 - 不要依赖
host.docker.internal—— 它只在特定平台有效,且 Traefik 不会自动替换该 host - 验证方式:进 Traefik 容器执行
ping my-golang-service,能通才说明网络连通
如何调试 traefik 找不到你的 Golang 服务
最常见的现象是 Traefik Dashboard 显示 “No routers found”,或请求返回 404/502,但日志里没明显报错。
- 先看 Traefik 日志:
docker logs traefik,搜索provider和configuration关键字,确认 Docker provider 是否成功初始化 - 检查容器标签是否生效:
docker inspect your-golang-container | grep -A 5 Labels,确认标签完整且无拼写错误(比如routers写成router) - 确认 Golang 服务已就绪:Traefik 会在容器
healthcheck通过后才启用路由,若服务启动慢,可加traefik.http.services.myapp.loadbalancer.healthcheck.interval=10s - 避免使用
localhost或127.0.0.1作为 Host 规则值,浏览器无法解析;改用app.test并配 hosts 文件,或直接用 IP+PathPrefix
真正卡住的地方往往不是配置语法,而是 Docker 网络隔离、标签拼写细节、或服务启动时机——这些地方没有报错提示,却让整个链路静默失败。


















