容器与平台
Traefik v3 配置 Let's Encrypt 自动 HTTPS
Traefik v3 用证书解析器自己申请和续期 Let's Encrypt 证书。Docker 容器加上四个标签,就能通过 https://example.com 访问,HTTP 自动跳转到 HTTPS。适用于 Docker Compose 部署的 Traefik v3.x(截至 2026 年 11 月参考文档对应 v3.7)。
前提条件
Traefik 需要独占主机的 80 和 443 端口。
- 装有 Docker Engine 和 Compose 插件的 Linux 主机。
example.com的 A/AAAA 记录指向主机,例如203.0.113.10;服务器在中国大陆的需已备案。- 防火墙和安全组放行 TCP 80、443。
- 一个项目目录,例如
/opt/traefik。
第一步:编写静态配置
静态配置文件 traefik.yml 定义 80 和 443 两个入口、HTTP 跳转和名为 le 的 Let's Encrypt 证书解析器:
# /opt/traefik/traefik.yml
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
le:
acme:
email: admin@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
docker:
exposedByDefault: false
Traefik 会在跳转生效之前处理 web 入口上的 ACME HTTP 验证请求,所以把所有 HTTP 流量跳转到 HTTPS 是安全的。
第二步:编写 Compose 文件
Compose 文件启动 Traefik 和一个示例服务,服务用 Docker 标签声明域名和证书解析器:
# /opt/traefik/compose.yaml
services:
traefik:
image: traefik:v3.7
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
whoami:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`example.com`)
- traefik.http.routers.whoami.entrypoints=websecure
- traefik.http.routers.whoami.tls.certresolver=le
镜像标签用 Traefik 文档里当前的 v3 版本。把 whoami 换成你自己的服务,保留这四个标签。
第三步:准备 acme.json 并启动
Traefik 把证书存在 acme.json 里,这个文件要提前创建并设为 600 权限:
cd /opt/traefik
mkdir -p letsencrypt
touch letsencrypt/acme.json && chmod 600 letsencrypt/acme.json
sudo docker compose up -d
sudo docker compose logs -f traefik
调试阶段在 acme: 下加 caServer: https://acme-staging-v02.api.letsencrypt.org/directory 使用测试环境,正式上线前删掉这行并清空 acme.json。
第四步(可选):用 DNS 验证申请通配符证书
把 httpChallenge 换成 lego 支持的 DNS 服务商,用环境变量传入密钥,在路由上声明通配符域名。以阿里云 DNS 为例:
certificatesResolvers:
le:
acme:
email: admin@example.com
storage: /letsencrypt/acme.json
dnsChallenge:
provider: alidns
environment:
- ALICLOUD_ACCESS_KEY=your-access-key-id
- ALICLOUD_SECRET_KEY=your-access-key-secret
labels:
- traefik.http.routers.whoami.tls.domains[0].main=example.com
- traefik.http.routers.whoami.tls.domains[0].sans=*.example.com
environment 写在 traefik 服务下,标签写在你的应用上。想申请 Let's Encrypt 的 45 天证书,在解析器里加 profile: tlsserver 和 certificatesDuration: 1080,见 Let's Encrypt 证书配置文件。
验证
配置正确时,证书颁发者是 Let's Encrypt,而不是 TRAEFIK DEFAULT CERT,HTTP 请求跳转到 HTTPS。用 SSL 证书检查 检查,或在终端运行:
curl ssl.sh/example.com
在主机上:
curl -sI http://example.com | head -n 3
sudo docker compose logs traefik | grep -iE 'acme|certificate' | tail -n 20
自动续期
Traefik 运行期间会在后台自动续期,不需要 cron。默认 certificatesDuration 为 2160 小时,即按 90 天证书处理、到期前 30 天开始续期。续期时间取决于这个设置而不是证书本身,所以有效期变化时要同步修改:Let's Encrypt 默认证书 2027 年 2 月 10 日改为 64 天、2028 年 2 月 16 日改为 45 天,届时以 Traefik 发布说明推荐的取值为准。把域名加到 ssl.sh 监控(开发中),确认续期确实发生。
常见问题排查
- permissions 644 for /letsencrypt/acme.json are too open:对文件执行
chmod 600。 - 浏览器显示 TRAEFIK DEFAULT CERT:路由没有引用解析器或签发失败,见 NET::ERR_CERT_AUTHORITY_INVALID 和 Traefik 日志。
- 日志里出现 Timeout during connect:80 端口到不了 Traefik(安全组、运营商封端口、未备案拦截),原因和 certbot 连接超时 相同。
- too many certificates already issued:
acme.json没有持久化,重启后反复申请,见 Let's Encrypt 频率限制。 - router uses a nonexistent resolver:
tls.certresolver里的名字和certificatesResolvers里定义的不一致。
常见问题
浏览器显示 TRAEFIK DEFAULT CERT 是怎么回事?
没有证书匹配请求的域名时,Traefik 会返回自带的自签名默认证书。常见原因是路由没写 tls.certresolver、Host() 规则不匹配,或者签发失败。查看 Traefik 日志里的 ACME 报错。
容器重启后证书会丢吗?
acme.json 没放在持久化卷上就会丢。那样 Traefik 每次启动都会重新申请证书,很快会触发 Let's Encrypt 频率限制。
国内服务器 80 端口不通怎么办?
443 能访问时可以用 tlsChallenge;80 和 443 都不通或域名未备案时用 dnsChallenge,域名在阿里云 DNS 就写 provider: alidns 并传入 ALICLOUD_ACCESS_KEY、ALICLOUD_SECRET_KEY,腾讯云 DNSPod 用 tencentcloud。