Traefik 使用进阶
2025 年 12 月 03 日
上个月搭建了家庭服务器,然后简单配置了 traefik 做为应用网关。虽然能用,但存在几个问题:
- 配置时需要手动修改文件,明显不方便。
- 安全性上,简单配置了 basic-auth 作为 middleware,但如果后端服务也依赖 basic-auth(比如 webssh2),就会产生冲突。
针对这两个问题,做了以下几个改进:
- 将原来的静态配置直接放到 docker-compose.yml 中,减少了配置文件。
- 使用 mantrae 提供 web 配置界面,免去手动修改配置文件。
- 使用 tinyauth 做 forward-auth,避免跟后端产生冲突。
记录一下对这部分的理解。
概念整理
域名 DDNS 映射和防火墙配置的思路前面都记录过,不再重复了。这里只需要整理一下概念。
Traefik 相关
- 入口点(entrypoint),可以简单理解为端口,比如 web(80)和 websecure(443)。
- 路由(router),即 traefik 提供的反向代理的配置描述。
- 静态配置,即 traefik 启动时必须的配置,可以通过 配置文件 或 command 提供。
- 动态配置,即 traefik 运行期所需的配置。
- 动态配置提供者(provider),可以选择以下几种的组合:
- 文件(file),通常是监视一个目录,目录下配置文件改动后就立刻生效。
- docker,traefik 会扫描 docker 节点,当新增 docker 包含对应的 labels 时,则自动生成路由。
- http,可以从 http 获取动态配置,比如 mantrae 即可以采用此方式提供配置。
- 中间件(middleware),在外部请求到达真正的服务(service)之前,traefik 会先让配置的 middleware 处理。所以 auth 就是很典型的中间件。
可以这样简单的理解 traefik 的工作方式。
- traefik 启动时,读取静态配置,按照配置开始工作。
- traefik 启动后,通过 provider 读取动态配置,然后动态添加 router,提供反向代理服务。
- 如果 provider 是 docker,则动态配置可以从 docker labels 读取。
- 如果 provider 是 file,则动态配置根据文件内容变更。
- 如果 provider 是 http,则动态配置为定时拉取。
- 外部请求到达 traefik 的 entrypoint 之后,traefik 根据 router 规则,如果有 middleware,就先由 middleware 处理。如果接下来还需要进一步处理,则转给真正的 service。
Mantrae 相关
本质上,mantrae 只是为 traefik 提供动态配置的一个 provider(注意:可以不包括全部动态配置)。
虽然好像也可以把证书交给 mantrae 处理,但我觉得……没必要啊。
Tinyauth 相关
tinyauth 是一个 forward-auth 中间件,traefik 对于这类中间件的处理方式是:
- 先将原始请求转发给 forward-auth 中间件处理,如果通过,则继续转发给 service。
- 如果不通过,则跳转到 forward-auth 中间件提供的登录页面,携带下一步跳转的 service 目标地址。
- 如果登录成功,则跳转 service。
- 如果登陆失败,则停在 forward-auth 的登录页面。
所以这里,tinyauth 本身就需要是一个 router。
完整配置示例及解析
该配置将 tinyauth,mantrae,traefik 放在一个 docker compose 中,共享同一个网络,也方便使用。
下面是脱敏后的 docker-compose.yml 示例:
services:
tinyauth:
image: ghcr.io/steveiliop56/tinyauth:v4
container_name: tinyauth
restart: unless-stopped
environment:
- APP_URL=https://tinyauth.example.com
- USERS=TINYAUTH_USER
labels:
- "traefik.enable=true"
- "traefik.http.routers.tinyauth.rule=Host(`tinyauth.example.com`)"
- "traefik.http.routers.tinyauth.tls.certResolver=myresolver"
- "traefik.http.services.tinyauth.loadbalancer.server.port=3000"
networks:
- ipv6_network
mantrae:
image: ghcr.io/mizuchilabs/mantrae:latest
container_name: mantrae
environment:
- SECRET=MANTRAE_SECRET
- ADMIN_PASSWORD=MANTRAE_ADMIN_PASSWORD
ports:
- "9000:3000"
volumes:
- ./mantrae:/data
restart: unless-stopped
networks:
- ipv6_network
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "9080:8080"
volumes:
- "./config:/etc/traefik"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
command:
- --log.level=INFO
- --api.dashboard=true
- --api.insecure=true
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.websecure.address=:443
- --entrypoints.traefik.address=:8080
- --providers.docker=true
- --providers.http.endpoint=http://mantrae:3000/api/default?token=MANTRAE_PROFILE_TOKEN
- --providers.http.pollinterval=5s
- [email protected]
- --certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme.json
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
networks:
- ipv6_network
depends_on:
- tinyauth
- mantrae
networks:
ipv6_network:
enable_ipv6: true
接下来是对于各部分配置的讲解。
tinyauth 配置要点
tinyauth 首先是个独立的服务。不受其他服务影响。
就像前面提到的,tinyauth 本身就是一个 router,因此这部分通过 labels 配置。
APP_URL 必须指向 router 对应的域名。
TINYAUTH_USER 可以通过docker run -i -t --rm ghcr.io/steveiliop56/tinyauth:v4 user create --interactive命令生成。多个用户以逗号隔开。
其他配置参考文档。
mantrae 配置要点
mantrae 用来管理 traefik,也是个独立服务,不过我觉得没必要把它暴露到外部,就没配置 router。
SECRET 可以通过 openssl rand -hex 16 命令生成,16/24/32 位都可以。
MANTRAE_ADMIN_PASSWORD 是明码。
MANTRAE_PROFILE_TOKEN 必须先启动一次 mantrae 后,在界面上获取。
traefik 配置要点
traefik 依赖于上面两个服务。
traefik 接管 80/443 端口,另外提供一个 dashboard 是只读的。
使用 command 配置,可以省掉静态配置文件。使用 mantrae 配置,可以省掉动态配置文件。
entrypoint 配置将 80 端口强制转向 443。
映射 volume 的 config 目录下需要有一个 acme.json 文件,权限 600。
provider 用 docker 的话,需要映射 docker volume。
MANTRAE_PROFILE_TOKEN 需要改写成从 mantrae 主界面获取的 token。
调试方式
结合 mantrae 和 traefik 的 dashboard(在上面例子中配置成了 9000 和 9080 端口),根据配置的状态进行分析。