冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

Docker与Traefik反向代理:自动HTTPS入门

浏览:61次阅读
没有评论

共计 4383 个字符,预计需要花费 11 分钟才能阅读完成。

每次新上一个服务,就要打开 Nginx 配置文件,复制一段 `server` 块,改域名、改端口、改 `proxy_pass`,再手动跑一遍 Certbot 签证书——这套流程你是不是已经重复了几十次?

**Traefik 干的事情,就是让你再也不用碰这些。**

它监听 Docker 的事件,容器一启动,路由自动生成,HTTPS 证书自动签发。你唯一要做的,是在 `docker-compose.yml` 里加几行标签。

## 为什么选 Traefik 而不是 Nginx

先说清楚:Nginx 本身没毛病,性能强悍、生态成熟。但在 Docker 多服务场景下,它有一个根本性的痛点——** 它不认识 Docker**。

每新增一个服务,你需要:

1. 手动编写反向代理配置
2. 手动申请 / 续期 SSL 证书
3. 手动 reload 使配置生效

Traefik 的核心优势在三个字:** 自动化 **。

| 对比项 | Nginx + Certbot | Traefik |
|—|—|—|
| 服务发现 | 手动配置 | 自动监听 Docker API |
| HTTPS 证书 | 手动申请 + 定时续期 | Let’s Encrypt 全自动 |
| 新增服务 | 改配置 + reload | 加 Label 启动即生效 |
| 配置方式 | 配置文件 | Docker Labels / 文件 / API |

一句话总结:**Nginx 是手动挡,Traefik 是自动挡。** 城市通勤(频繁增删服务),自动挡省心太多。

## Traefik 的核心概念

在动手之前,花两分钟搞懂四个关键词,后面的配置就不会一头雾水。

### EntryPoints:流量入口

就是 Traefik 监听的端口。最常见的配置是两个:`80`(HTTP)和 `443`(HTTPS)。

### Routers:路由规则

决定 ” 什么样的请求,送到哪个服务 ”。比如域名是 `app.example.com` 的请求,路由到你的 Web 应用容器。

### Services:后端服务

实际处理请求的目标,对应你的 Docker 容器。Traefik 会自动发现容器暴露的端口,把请求转发过去。

### Middlewares:中间件

在请求到达服务之前做一些处理,比如 HTTP 跳转 HTTPS、添加请求头、限流、Basic Auth 等。

** 整个流程就是 **:请求进入 EntryPoint → Router 匹配规则 → Middleware 预处理 → 转发到 Service。

像一条流水线,每个环节各司其职。

## 实战:从零搭建 Traefik + 自动 HTTPS

### 第一步:准备目录结构

“`bash
mkdir -p ~/traefik && cd ~/traefik
touch docker-compose.yml
touch acme.json
chmod 600 acme.json
“`

`acme.json` 用来存储 Let’s Encrypt 颁发的证书,权限必须是 600,否则 Traefik 会拒绝启动。

### 第二步:编写 Traefik 的 docker-compose.yml

“`yaml
version: “3.8”

services:
traefik:
image: traefik:v3.1
container_name: traefik
restart: unless-stopped
command:
– “–api.dashboard=true”
– “–providers.docker=true”
– “–providers.docker.exposedbydefault=false”
– “–entrypoints.web.address=:80”
– “–entrypoints.websecure.address=:443”
– “–certificatesresolvers.letsencrypt.acme.email=you@example.com”
– “–certificatesresolvers.letsencrypt.acme.storage=/acme.json”
– “–certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web”
ports:
– “80:80”
– “443:443”
volumes:
– /var/run/docker.sock:/var/run/docker.sock:ro
– ./acme.json:/acme.json
labels:
– “traefik.enable=true”
# Dashboard 路由(可选)
– “traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)”
– “traefik.http.routers.dashboard.entrypoints=websecure”
– “traefik.http.routers.dashboard.tls.certresolver=letsencrypt”
– “traefik.http.routers.dashboard.service=api@internal”

networks:
default:
name: traefik-net
external: true
“`

几个关键配置解释一下:

– **`providers.docker=true`**:告诉 Traefik 从 Docker 自动发现服务
– **`exposedbydefault=false`**:不自动暴露所有容器,只有显式声明 `traefik.enable=true` 的才会被代理(安全最佳实践)
– **`httpchallenge.entrypoint=web`**:使用 HTTP-01 验证方式申请证书,Let’s Encrypt 会访问你的 80 端口进行验证

启动前先创建 Docker 网络:

“`bash
docker network create traefik-net
“`

然后启动 Traefik:

“`bash
docker compose up -d
“`

### 第三步:部署一个业务服务

假设你有一个 Web 应用,想通过 `app.example.com` 访问。在项目目录下创建 `docker-compose.yml`:

“`yaml
version: “3.8”

services:
webapp:
image: your-app-image:latest
container_name: webapp
restart: unless-stopped
labels:
– “traefik.enable=true”
– “traefik.http.routers.webapp.rule=Host(`app.example.com`)”
– “traefik.http.routers.webapp.entrypoints=websecure”
– “traefik.http.routers.webapp.tls.certresolver=letsencrypt”
– “traefik.http.services.webapp.loadbalancer.server.port=3000”

networks:
default:
name: traefik-net
external: true
“`

** 注意两点 **:

1. 业务容器必须加入 `traefik-net` 网络,否则 Traefik 无法转发请求
2. `loadbalancer.server.port` 指定容器内部监听的端口,不是宿主机映射端口

执行 `docker compose up -d`,等待几秒钟,访问 `https://app.example.com`——证书已经自动签好了。

** 没有改任何 Traefik 的配置文件。** 这就是自动服务发现的魅力。

## 全局 HTTP 跳转 HTTPS

现在访问 `http://app.example.com` 还是会停留在 HTTP。加一个全局中间件搞定:

在 Traefik 的 `command` 中追加一行:

“`yaml
– “–entrypoints.web.http.redirections.entrypoint.to=websecure”
“`

重启 Traefik 后,所有 80 端口的请求会自动 301 跳转到 443。一行配置,全局生效。

## 常见问题排查

### 证书申请失败

90% 的原因是域名的 DNS 没有正确解析到服务器 IP。Let’s Encrypt 的 HTTP-01 验证需要从公网访问你的 80 端口。

** 排查清单 **:

– 域名 A 记录是否指向服务器公网 IP
– 服务器防火墙是否放行 80 和 443 端口
– `acme.json` 权限是否为 600

### 容器启动了但访问 502

Traefik 找到了路由规则,但无法连接到后端服务。通常是以下原因:

– 业务容器和 Traefik 不在同一个 Docker 网络
– `loadbalancer.server.port` 写的端口与容器实际监听的端口不一致

### Dashboard 无法访问

确认 Dashboard 的域名已解析,并且 Labels 中的域名与你访问的一致。** 生产环境强烈建议给 Dashboard 加上 BasicAuth 中间件 **,否则任何人都能看到你的路由拓扑。

## 多服务扩展:加一个服务有多简单

当你要部署第二个服务(比如 `api.example.com`),只需要:

“`yaml
labels:
– “traefik.enable=true”
– “traefik.http.routers.api.rule=Host(`api.example.com`)”
– “traefik.http.routers.api.entrypoints=websecure”
– “traefik.http.routers.api.tls.certresolver=letsencrypt”
– “traefik.http.services.api.loadbalancer.server.port=8080″
“`

五行 Labels,启动容器,证书自动签发,路由自动生效。

** 不改 Traefik 配置,不 reload 任何服务。**

如果同一个服务跑了多个副本(`docker compose up –scale webapp=3`),Traefik 会自动对这三个容器做负载均衡,默认轮询策略,不需要额外配置。

## 写在最后

Traefik 并不是要 ” 取代 ” Nginx。如果你只有一两个静态站点,Nginx 依然简单好用。

但当你的服务器上跑着 5 个、10 个甚至更多 Docker 服务,每个都需要独立域名和 HTTPS 证书时,Traefik 的自动化能力会帮你省下大量重复劳动。

** 把时间花在写代码上,别花在写 Nginx 配置上。**

> 建议下一步:阅读 Traefik 官方文档中 Middlewares 章节,了解限流、IP 白名单、请求头重写等进阶用法——这些才是生产环境真正需要的安全加固手段。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-24发表,共计4383字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。
评论(没有评论)