本篇文章聊聊在阿里云环境中,目前使用的一套 Traefik 配置方案。
这套方案的目标很简单:新服务上线不需要修改 Traefik 配置、自动申请和续签 SSL 证书、最小权限访问阿里云 DNS、支持大量业务服务长期维护、迁移服务器成本尽可能低。
写在前面
最近在整理团队服务器,将域名管理切换到了阿里云。因此,之前基于 Cloudflare DNS Challenge 的证书自动签发配置,也需要同步调整。借着这次迁移的机会,我顺便把 Traefik 的整体配置重新整理了一遍。
如果你还不熟悉 Traefik 的基础部署和使用,可以先阅读:《Docker 环境下使用 Traefik 3 的最佳实践:快速上手》。
方案设计
在开始部署之前,先聊聊这套方案为什么这样设计。
很多人在使用 Traefik 的时候,会直接把所有业务域名都写在 Traefik 的配置文件中:
example.com
api.example.com
app.example.com
服务越来越多之后,Traefik 配置会越来越长。
每新增一个服务,都需要做下面的事情:修改 Traefik 配置、重启 Traefik、检查证书、验证路由。
这样下去,维护成本会越来越高。
因此,一直以来我更倾向于:Traefik 只负责入口,业务服务自己声明域名和路由规则。
例如:
labels:
- traefik.http.routers.blog.rule=Host(`app.example.com`)
其实,证书需求也应该由业务来声明。
这样做会有下面几个明显优点。
服务自治
新增服务时,只需要执行下面的命令,就能够自动接入:
docker compose up -d
不需要再调整 Traefik 的配置,包括接入新的域名。
配置解耦
Traefik 不关心业务;业务也不关心 Traefik 内部实现,两者完全解耦。
更容易迁移
未来迁移服务器时,只需要把所有配置带走,就可以跨机器直接部署,恢复服务:
scp compose.yaml
docker compose up -d
所有服务配置,都跟随业务一起迁移,而不锁定网关。
DNS Challenge 的优势
这里没有选择 HTTP Challenge,而是选择 DNS Challenge 的原因很简单:DNS Challenge 支持通配符证书。
例如,我们可以申请 *.yourdomain.ltd,申请完毕之后:
api.yourdomain.ltd
grafana.yourdomain.ltd
harbor.yourdomain.ltd
这类域名就都可以通过 HTTPS 进行访问了,未来新增类似的服务无需重新申请证书。以及这样做也不依赖公网 80 端口、可以用于内网服务、灵活性也更高。
安全设计
因为自动签发证书需要修改 DNS,因此需要阿里云 API 权限。这里不建议直接使用主账号,而是使用有限权限的 RAM 账号进行操作。规避因为主账号权限太大,一旦泄露各种账号资源都有风险的问题。
让 Traefik 只能查询域名、创建 TXT 记录、删除 TXT 记录,禁止访问其他资源,这样即使密钥泄露,影响范围也非常有限。
初始化阿里云相关资源
为了更低的维护成本,在部署和使用 Traefik 之前,我们首先要初始化一些阿里云上的资源:运行 Traefik 和相关 Web 服务的服务器、能够更新指定域名的账号。
服务器我使用 Ubuntu 26.04 操作系统的 ECS,其他版本的操作系统类似,只要能够使用 Docker 运行服务即可。如果你还不熟悉配置 Docker 环境,可以参考《搭建 Ubuntu 24.04 基础开发环境指南》几条命令完成 Docker 的安装和基础配置。
为了整个账号下资源安全,我们需要创建一个独立的 RAM 账号,缩小权限范围到只能操作指定域名,来配合 Traefik 进行指定域名的 SSL 证书持续的自动申请。
我们先访问 RAM 控制台,创建一个新的账号。

创建账号时,关闭访问控制台访问权限,仅允许 API 调用。

创建完毕,保存好用户的 ACCESS KEY 和 ACCESS KEY SECRET,我们后续要使用。
接着,先创建域名全局查询策略。

因为 Traefik 会调用 DescribeDomains,需要 "Resource": "*"权限,所以我们的配置需要这样写:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"alidns:DescribeDomains"
],
"Resource": "*"
}
]
}
完成之后,我们继续创建第二个策略,这个策略允许进行指定域名的编辑:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"alidns:AddDomainRecord",
"alidns:DeleteDomainRecord",
"alidns:UpdateDomainRecord",
"alidns:DescribeDomainRecords"
],
"Resource": [
"acs:alidns:*:*:domain/yourdomain.ltd"
]
}
]
}
上面配置中的 yourdomain.ltd 就是我们要使用 Traefik 自动申请证书的域名。

完成之后,分别将两个策略关联到我们上面创建的用户上。
然后,我们开始配置 Traefik。
Traefik基础配置
在进行配置和部署服务之前,我们需要确认:
域名已经解析到服务器(或者手动绑定本地 hosts 到目标服务器)、ECS 安全组开放 80、443 的公网访问,Docker 已正常安装。
这里使用独立的 Docker 网络:
docker network create traefik
这样做的好处是,未来所有业务服务想要通过 Traefik 提供服务时,都只需要在配置中加入下面的内容:
networks:
- traefik
即可自动被 Traefik 发现,提供被访问能力,而无需额外暴露端口(无额外端口占用)。
如果不这样做,我们始终需要声明容器的可访问端口,例如:
ports:
- 8080:8080
有了独立的 Docker 网络后,上面这样的配置就可以省略了,也减少了不必要的公网暴露。
Traefik 配置说明
使用 SSH 登录服务器后,我们先创建一个存放 Traefik 配置的目录,并切换工作目录:
mkdir traefik
cd traefik/
然后,编写容器配置 compose.yaml:
name: traefik
services:
traefik:
image: ghcr.io/traefik/traefik:3.6
container_name: traefik
restart: unless-stopped
env_file:
- .env
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --entrypoints.http.http.redirections.entrypoint.to=https
- --entrypoints.http.http.redirections.entrypoint.scheme=https
- --certificatesresolvers.aliyun.acme.email=${ACME_EMAIL}
- --certificatesresolvers.aliyun.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.aliyun.acme.dnschallenge=true
- --certificatesresolvers.aliyun.acme.dnschallenge.provider=alidns
- --certificatesresolvers.aliyun.acme.dnschallenge.delaybeforecheck=10
- --ping=true
- --ping.entrypoint=traefik
- --entrypoints.traefik.address=:8080
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/letsencrypt:/letsencrypt
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
security_opt:
- no-new-privileges:true
networks:
- traefik
networks:
traefik:
external: true
在上面的配置中,Traefik 仅处理 ACME证书申请,不再需要保存任何业务域名,更利于维护。
接着,创建这个配置需要的 .env文件,将细节配置和刚刚创建的阿里云账号的 AK 和 SK 写入配置:
# Let's Encrypt 通知邮箱
ACME_EMAIL=ops@yourdomain.ltd
# 阿里云 DNS API
ALICLOUD_ACCESS_KEY=xxxxxxxxxxxxxxxx
ALICLOUD_SECRET_KEY=xxxxxxxxxxxxxxxx
# 可选:调试环境
TZ=Asia/Shanghai
完成之后,在目录中执行命令 docker compose up -d,能够看到服务就正常运行起来了:
# docker compose up -d
[+] up 2/4
✔ Image ghcr.io/traefik/traefik:3.6 Pulled 11.2s
✔ Container traefik Started
稍等几秒,执行 docker ps ,或 docker inspect traefik 可以检查容器运行是否正常:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
947d3b6c3d0d ghcr.io/traefik/traefik:3.6 "/entrypoint.sh --pr…" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp traefik
# docker inspect traefik --format='{{json .State.Health}}' | jq
{
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"Start": "2026-05-29T20:56:22.98906195+08:00",
"End": "2026-05-29T20:56:23.038763907+08:00",
"ExitCode": 0,
"Output": "OK: http://:8080/ping\n"
},
{
"Start": "2026-05-29T20:56:53.040007578+08:00",
"End": "2026-05-29T20:56:53.091085376+08:00",
"ExitCode": 0,
"Output": "OK: http://:8080/ping\n"
}
]
}
到此,基本的配置就都完成了。
Docker Provider
上面的配置中,指定了 --providers.docker=true,这个配置是关键配置之一,开启后 Traefik 会自动监听 Docker 事件。
我们无需重启 Traefik 容器,就能够让各种业务容器的配置自动生效。
统一 HTTPS 访问
--entrypoints.http.http.redirections.entrypoint.to=https
为了避免业务提供不安全的 HTTP 访问,我们默认强制所有请求都是 HTTPS,非 HTTPS 的请求会被自动跳转。
自动续签证书
--certificatesresolvers.aliyun.acme
使用这个配置后,Traefik 会自动续签证书,正常情况下无需人工维护。
自动健康检查
healthcheck:
可以让 Docker 自动判断 Traefik 状态,避免入口服务异常却无法及时发现。
配置自动申请证书的服务
让我们来配置自动申请证书的服务。
切换到上级目录,或你计划存放这些服务的工作目录,然后创建一个新的工作目录,来存放用来自动申请证书的 Web 服务。
cd ..
mkdir service-for-issue-domain
cd service-for-issue-domain/
这次让我们先创建 .env 文件,明确我们要创建的服务信息:允许被访问的 URL 域名、计划申请证书要包含的域名列表、要使用的容器镜像名称等。
# Domain
APP_NAME=whoami
APP_DOMAIN=whoami.yourdomain.ltd
# TLS
ACME_MAIN_DOMAIN_1=yourdomain.ltd
ACME_MAIN_DOMAIN_2=sub.yourdomain.ltd
# Container
IMAGE=ghcr.io/traefik/whoami
IMAGE_TAG=v1.11
# Docker
TZ=Asia/Shanghai
接着,创建 compose.yaml:
name: ${APP_NAME}
services:
app:
image: ${IMAGE}:${IMAGE_TAG}
container_name: ${APP_NAME}
restart: unless-stopped
environment:
TZ: ${TZ}
expose:
- 80
labels:
- traefik.enable=true
- traefik.docker.network=traefik
# Router
- traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DOMAIN}`)
- traefik.http.routers.${APP_NAME}.entrypoints=https
- traefik.http.routers.${APP_NAME}.tls=true
- traefik.http.routers.${APP_NAME}.tls.certresolver=aliyun
# Wildcard Certificate
- traefik.http.routers.${APP_NAME}.tls.domains[0].main=${ACME_MAIN_DOMAIN_1}
- traefik.http.routers.${APP_NAME}.tls.domains[0].sans=*.${ACME_MAIN_DOMAIN_1}
- traefik.http.routers.${APP_NAME}.tls.domains[1].main=${ACME_MAIN_DOMAIN_2}
- traefik.http.routers.${APP_NAME}.tls.domains[1].sans=*.${ACME_MAIN_DOMAIN_2}
- traefik.http.services.${APP_NAME}.loadbalancer.server.port=80
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
compress: "true"
networks:
- traefik
networks:
traefik:
external: true
在这个配置中,我们创建了一个能够被用户通过 whoami.yourdomain.ltd 访问的服务,这个服务将会自动的申请证书,申请的证书支持配置 yourdomain.ltd,*.yourdomain.ltd,*.sub.yourdomain.ltd中包含的任何域名。
使用 docker compose up -d 启动服务后,访问 https://whoami.yourdomain.ltd,就能够看到正常使用 SSL 证书的 whoami 服务页面啦。
最后
相比传统 Nginx 或集中式 Traefik 配置,这套方案最大的特点是:入口与业务彻底解耦。
Traefik 只负责:服务发现、路由转发、TLS 管理;而业务服务负责:域名声明、路由规则、生命周期管理。
当我们新增服务时,只需要执行:docker compose up -d 就可以完成服务上线、HTTPS 配置、证书申请、自动续签等一系列工作,而无需修改 Traefik 配置。
对于长期维护几十甚至上百个服务的环境来说,这种方式会比传统配置轻松很多。
–EOF