Docker容器——traefik
点击展开更新日志
2025
11-23
【新增】创建了这篇文章,几乎完成了所有内容
nexttime
会有些什么呢(❁´◡`❁)
¶源起
其实也没有特别的起因,只是突然想折腾,想找个网关应用做 Docker 统一入口。那么,原来的 openresty 不香了吗?真要从功能性上说,感觉二者差不多,第一次需要配置的内容也不少,单纯就是想折腾了。
¶概要
引用官网介绍: “Traefik 是您的一站式、自托管、云原生、基于 GitOps 驱动的应用代理、API 网关和 API 管理平台。”当然,这是商业版的功能,我们能免费用的开源版本就只有描述的一丢丢功能了。
简言之,traefik(发音:traffic) 也是一款反向代理和负载均衡器,只是相较于 Nginx,与 Docker,k8s 容器环境适配性更高:
- 能够读取 Docker 标签(label) 进行配置
- 动态配置:可以直接监听 Docker 守护进程,自动发现容器并自动配置路由、证书(需要提前配置好规则)
¶部署
环境要求:
- Docker/Docker compose(建议)
- (建议)SSL证书
- htpasswd 工具,可以用网页工具,搜一下就有
以下部署文件结合了官方文档和实际情况,仅供参考:
1 | services: |
-
创建容器目录
1
mkdir -p /data/docker/traefik/{certs,dynamic}
- certs: 保存SSL证书
- dynamic: 动态配置
-
将以上内容保存为
docker-compose.yml文件已对各配置项进行了必要说明,如果仍有疑问请自行查询。
-
将证书放到
certs目录下,比如文件名为:cert.crt,key.pem -
在
dynamic目录下创建文件tls.yaml1
2
3
4
5# tls.yaml
tls:
certificates:
- certFile: /certs/cert.crt
keyFile: /certs/key.pem -
启动服务
-
测试验证
此时就可以通过域名访问管理面板了。如果暂时不需要证书或者想通过ip访问,注释/删除 https 相关部分,同时将--api.insecure=false设置为 false。
¶Docker 服务配置
现在就需要将我们的 Docker 服务纳入 traefik 进行配置,实现方式就只需要为应用加上相关标签配置即可。
以 adguardHome 为例,在 docker-compose.yml 中添加 traefik 标签:
1 | services: |
然后重新部署,确认好域名解析正确(需要解析到 traefik 所在服务),就可以在管理面板看到新增的 adguardHome 服务,就可以通过域名访问了。此外,原本保留的管理端口 3000 映射也可以选择注释掉,通过 traefik 内部网络路由,不直接对外。
总结,将已有应用集成到 traefik 需要做的配置:
- 移除端口映射
- 添加 traefik 标签
- 确保容器和 traefik 处于同一容器网络。那么是否可以将 traefik 默认的
app网络加到每个容器呢,至少在我的环境中不可行(cloudbeaver无法连接数据库,仅保留单一内部网络正常),所以不考虑了。
如果你想让一个域名下的不同路径代理到不同的服务,可以使用 PathPrefix 规则:
1 | # 示例:通过路径代理到服务 A |
¶非 Docker 服务配置
其它一些比如 pve 或网络模式为 host 的服务也可以使用 traefik 代理,这里就需要使用 traefik file provider,以 pve 为例。
-
启动
file provider:1
2
3
4
5
6# 原始配置
- "--providers.file.filename=/dynamic/tls.yaml"
# ➡️ 修改为:加载整个目录
- "--providers.file.directory=/dynamic"
- "--providers.file.watch=true" # 启用监控,文件更改后自动更新 -
在
dynamic目录下新增pve.yaml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31# dynamic/pve.yaml
http:
# 1. 定义路由器 (Router)
routers:
pve-router:
# ⚠️ 关键:使用 websecure 入口点 (443)
entryPoints:
- websecure
# 路由规则:匹配 pve.mydomain.com 域名
rule: Host(`pve.mydomain.com`)
service: pve-service
# 启用 TLS
tls: true
# 2. 定义服务 (Service)
services:
pve-service:
loadBalancer:
servers:
# ⚠️ 关键:指向 PVE 的 IP 和默认 HTTPS 端口 8006
- url: "https://192.168.1.100:8006"
# PVE 使用自签名证书,需要告诉 Traefik 忽略证书验证
serversTransport: pve-transport
# 3. 定义传输配置 (ServersTransport)
# 用于处理 PVE 的自签名证书
serversTransports:
pve-transport:
# ⚠️ 关键:跳过后端 HTTPS 证书验证
insecureSkipVerify: true- traefik 默认支持 websocket,因此无需特别配置。
-
重新部署
¶证书
当前我的情况是配置了通知手动做更新,还没有试过 traefik 自带的,先空着,有时间弄了再补充。
¶解惑
指定服务端口:- "traefik.http.services.homepage.loadbalancer.server.port=3000"这行是否是必要的,为什么使用loadbalancer?
“traefik.http.services.homepage.loadbalancer.server.port=3000” 是必要的,但并不是因为真的在“负载均衡”。它的作用是告诉 Traefik:“Homepage 容器内部的服务端口是 3000。”
当 Traefik 收到一个针对 homepage.mydomain.top 的请求时,它会查找名为 homepage 的服务定义,然后使用该定义中的端口号 3000,通过 Docker 内部网络将请求转发给 homepage 容器。如果没有显式指定 3000 端口,traefik 会查找 Docker 镜像元数据中定义的第一个暴露端口,可能会转发失败。
使用 loadbalancer 是因为这是 Traefik Service 的唯一类型,即使你只有一个后端容器(您的 homepage 实例),Traefik 也把它看作是一个负载均衡器,只不过这个负载均衡器只有一个后端目标。
容器配置traefik.enable=true有什么作用,有无安全风险,是否对外暴露端口?
作用是启动服务发现,因为在 traefik 配置中配置了:
1 | # 在 traefik 服务的 command 中 |
默认情况下,不会代理任何容器,使用 traefik.enable=true 标签就是明确告诉 traefik 代理当前容器。本身不会对外暴露端口。
如果pve有多个实例(集群部署),如何配置多个ip端口
对于 PVE 集群或具有多个后端实例的服务,只需要在 loadBalancer 的配置下添加多个 server URL 即可。
1 | # dynamic/pve.yaml (修改后的 Service 部分) |
默认使用轮询(roundrobin)进行流量分发,对于PVE需要保持用户会话的应用,可以配置粘性会话(Cookie-based Affinity):
1 | # 示例:启用基于 Cookie 的粘性会话 |
这里的 httpOnly: true 表示当一个 Cookie 设置了 httpOnly: true 属性后,该 Cookie 将无法通过客户端脚本(例如 JavaScript 中的 document.cookie API)被访问、读取或修改。主要目的是防御 XSS(跨站脚本工具)。
portainer 配置 traefik 之后域名访问报错:ERR_HTTP2_PROTOCOL_ERROR
这是因为双重HTTPS导致,Traefik 向 Portainer 的 9443 端口发送了一个 HTTP 请求,但 Portainer 期望收到一个 TLS/HTTPS 握手请求。Portainer 无法理解这个非加密的请求,因此立即关闭连接,导致 Traefik 无法完成响应,最终浏览器收到 ERR_HTTP2_PROTOCOL_ERROR。
需要在标签中加入 - "traefik.http.services.potainer.loadbalancer.server.scheme=https" ,明确说明使用 https 访问后端。





