

初印象#
Traefik 是一个开源的、云原生的 HTTP 反向代理和负载均衡器,专为微服务架构和容器化环境设计。其核心特点是动态配置和自动化服务发现
这话很多人都说烂了,我第一次知道 Traefik 是在 Halo 上的文档1上看到的,使用 Traefik 的反向代理和别的不太一样,它是使用 lable 来定义的,我当时觉得很新奇,因为从 compose 里面,并没有使用 ports 来定义暴露服务端口:
networks:
traefik:
external: true
halo:
services:
halo:
image: registry.fit2cloud.com/halo/halo:2.21
restart: on-failure:3
volumes:
- ./halo2:/root/.halo2
networks:
- traefik
- halo
command:
# 外部访问地址,请根据实际需要修改
- --halo.external-url=https://yourdomain.com
labels:
traefik.enable: "true"
traefik.docker.network: traefik
traefik.http.routers.halo.rule: Host(`yourdomain.com`)
traefik.http.routers.halo.tls: "true"
traefik.http.routers.halo.tls.certresolver: myresolver
traefik.http.services.halo.loadbalancer.server.port: 8090yaml体验#
不想按照官网的文档来介绍 Traefik,个人感觉写得有点云里雾里,让我们来尝试实际部署一个 Docker 服务,这里我使用的范例服务是:云函数部署 | Twikoo 文档 ↗
创建 Treafik#
我们将在一个专用的 docker-compose.yml 文件中定义 Traefik 服务,并让它连接到一个专用的 Docker 网络
首先得创建一个 Docker 网络,这是为了 Traefik 能发现外部的 docker-compose 服务:
docker network create webbash现在,创建 Traefik 的 docker-compose.yml (和它的静态配置文件 traefik.yml)
/opt/traefik/
├── docker-compose.yml
├── traefik.yml
└── letsencrypt/
└── acme.json (这个文件 Traefik 会自动创建)bash之后创建 docker-compose 文件,请不要急着启动容器:
services:
traefik:
image: traefik:v3.6 # 使用明确的版本号
container_name: traefik
restart: always
ports:
- "80:80" # HTTP 端口
- "443:443" # HTTPS 端口
volumes:
# 挂载 Docker Socket,以便 Traefik 可以监听 Docker 事件
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/etc/traefik/traefik.yml:ro"
- "./letsencrypt/acme.json:/letsencrypt/acme.json"
networks:
- web
networks:
web:
external: trueyml之后再创建 traefik.yml:
# --- 日志 ---
log:
level: INFO # (DEBUG, INFO, WARN, ERROR)
# --- 入口点 (EntryPoints) ---
entryPoints:
web:
address: ":80"
# 注意:不在 entryPoint 级别配置全局重定向,以允许 HTTP 挑战
# HTTP 到 HTTPS 重定向将在路由级别通过中间件配置
websecure:
address: ":443"
# (可选) 在这里全局设置 TLS
# http:
# tls: {}
# --- 证书解析器 (Let's Encrypt) ---
certificatesResolvers:
mycfresolver:
acme:
# Let's Encrypt 生产环境(默认)
# 测试环境使用: caServer: https://acme-staging-v02.api.letsencrypt.org/directory
# 存储类型和路径(与 docker-compose.yaml 中的挂载路径一致)
storage: /letsencrypt/acme.json
# 使用 HTTP 挑战(需要端口 80 可访问)
httpChallenge:
entryPoint: web
# 邮箱(用于 Let's Encrypt 通知,请替换为您的邮箱)
email: test@example.com
# --- Docker Provider 配置 ---
providers:
docker:
exposedByDefault: false # 最佳实践: 只有带 'traefik.enable=true' 的容器才会被暴露
network: web # 关键: 只监听 'web' 网络上的容器yaml这里的 /letsencrypt/acme.json 是用来控制证书的,有点坑,需要在容器启动前进行创建,并且需要给对应的权限:
touch ./letsencrypt/acme.json
chmod 600 ./letsencrypt/acme.jsonbash此时可以启动容器了:
docker compose up -dbash创建 Web 服务#
我们也使用 docker-compose.yml 来创建 Twikoo 服务
services:
twikoo:
image: imaegoo/twikoo
container_name: twikoo
restart: unless-stopped
# 移除直接端口映射,通过 Traefik 访问
environment:
TWIKOO_THROTTLE: 1000
TWIKOO_IP_HEADERS: '["headers.cf-connecting-ip"]'
volumes:
- ./data:/app/data
networks:
- web
labels:
# 启用 Traefik
- "traefik.enable=true"
# # 路由规则:访问`twikoo.example.com`,也就是这个服务对应外部的域名
- "traefik.http.routers.twikoo.rule=Host(`twikoo.example.com`)"
# 使用 HTTPS 入口点
- "traefik.http.routers.twikoo.entrypoints=websecure"
# 配置 TLS 证书(使用 Let's Encrypt)
- "traefik.http.routers.twikoo.tls.certresolver=mycfresolver"
# 指定后端服务端口
- "traefik.http.services.twikoo.loadbalancer.server.port=8080"
networks:
web:
external: trueyaml这里面比较重要的配置在 labels 里面,需要自定义,业务逻辑可以用这张图表示:

里面非常有意思的是,Twikoo 的 8080 端口从未暴露在宿主机,只有 Traefik 的网络可以访问它,不用担心因为 Docker Networks 修改本地机器的 iptables,从而导致 ufw 不能正确阻断端口的问题2
总结#
俺又心动了,尤其是对于我这种几乎所有服务都跑在容器上的人来说,Traefik 不用让我再次反反复复去折腾各种配置文件,只需要在 labels 中对服务进行声明即可,这非常地高效,而且它和 Caddy 一样给出了自动化 TLS 的功能