人生理想,技术交流加Q:411239339

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

浏览:10次阅读
没有评论

共计 4094 个字符,预计需要花费 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

第一步:准备目录结构

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

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 网络:

docker network create traefik-net

然后启动 Traefik:

docker compose up -d

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

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

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 中追加一行:

- "--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),只需要:

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发表,共计4094字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。