JuniorTree

Back

Traefik 初体验Blur image

初印象#

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: 8090
yaml

体验#

不想按照官网的文档来介绍 Traefik,个人感觉写得有点云里雾里,让我们来尝试实际部署一个 Docker 服务,这里我使用的范例服务是:云函数部署 | Twikoo 文档

创建 Treafik#

我们将在一个专用的 docker-compose.yml 文件中定义 Traefik 服务,并让它连接到一个专用的 Docker 网络

首先得创建一个 Docker 网络,这是为了 Traefik 能发现外部的 docker-compose 服务:

docker network create web
bash

现在,创建 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: true
yml

之后再创建 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.json
bash

此时可以启动容器了:

docker compose up -d
bash

创建 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: true
yaml

这里面比较重要的配置在 labels 里面,需要自定义,业务逻辑可以用这张图表示:

里面非常有意思的是,Twikoo 的 8080 端口从未暴露在宿主机,只有 Traefik 的网络可以访问它,不用担心因为 Docker Networks 修改本地机器的 iptables,从而导致 ufw 不能正确阻断端口的问题2

总结#

俺又心动了,尤其是对于我这种几乎所有服务都跑在容器上的人来说,Traefik 不用让我再次反反复复去折腾各种配置文件,只需要在 labels 中对服务进行声明即可,这非常地高效,而且它和 Caddy 一样给出了自动化 TLS 的功能

Footnotes#

  1. Halo 文档

  2. GitHub - chaifeng/ufw-docker: To fix the Docker and UFW security flaw without disabling iptables

Traefik 初体验
https://www.juniortree.com/blog/first-try-traefik
Author liueic
Published at 2025年11月13日
Comment seems to stuck. Try to refresh?✨