前言 {#前言}
对于家里面要部署很多 Docker
服务,用 Nginx
反向代理属实麻烦,所以就有了本篇文章 Traefik
Traefik
的logo 是一个 go
吉祥物进行指挥交通(流量)。
所以 Traefik
的好处是自动发现服务,自动配置反向代理,以及自动续签SSL,以及不在需要对外暴露额外的端口了,宿主机自始至终之暴露 80 443 端口。但也有诸多问题例如它并不能像 Nginx
一样可以灵活的配置反代一些程序,例如配置不在 Docker
部署的程序,会有点麻烦,如果想我一样只是作为本地部署项目 Traefik
仍然是一个不错的选择。
正文 {#正文}
在快速启动前,有必要说明一下,本教程是使用 CloudFlare
作为域名ns进行申请泛域名证书,如果你想使用其他提供商,可以在 Traefik 的文档 更改 Provider Code
和 Environment Variables
这两个值,当然我会在本篇配置文件有注释提醒。
另外如果没有额外配置反代的需求(指不跑在docker的服务),需要建立 config.yml
文件,当然还需要在 traefik.yml
关闭注释。
快速启动 Traefik {#快速启动-Traefik}
请按照一下文件目录创建文件,其中 acme.json
只需要创建文件即可(注意必须要交建立哦,config文件根据自己需求建立即可)
文件目录:
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7
| | .env #文件配置 | docker-compose.yaml # docker-compose 文件 | \---data acme.json # SSL 文件 config.yml # 额外配置文件(配置额外反代例如宿主机的) traefik.yml # Traefik 配置文件
|
docker-compose.yaml
文件:
|------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| services: traefik: # 定义名为 traefik 的服务 image: traefik:v3.0 # 使用 Traefik 的 v3.0 版本镜像 container_name: traefik # 容器名称为 traefik restart: unless-stopped # 容器自动重启,除非手动停止 security_opt: - no -new-privileges:true # 增加安全性,防止提权 networks: - traefik-net # 连接到名为 proxy 的外部网络 ports: - 80 :80 # 映射主机的 80 端口到容器的 80 端口 (HTTP) - 443 :443 # 映射主机的 443 端口到容器的 443 端口 (HTTPS) - 443 :443/tcp # 映射主机的 443 TCP 端口到容器的 443 端口 (TCP 协议) - 443 :443/udp # 映射主机的 443 UDP 端口到容器的 443 端口 (UDP 协议) environment: CF_DNS_API_TOKEN_FILE: ${CF_DNS_API_TOKEN} # 设置环境变量,使用 Cloudflare API 令牌,根据Traefik文档 选择你的服务提供商的token TRAEFIK_DASHBOARD_CREDENTIALS: ${TRAEFIK_DASHBOARD_CREDENTIALS} # 设置环境变量,定义 Traefik 仪表板的凭据 env_file: .env # 从 .env 文件中加载环境变量 volumes: - /etc/localtime:/etc/localtime:ro # 挂载主机的时间设置到容器,确保时间同步,且只读 - /var/run/docker.sock:/var/run/docker.sock:ro # 挂载 Docker 的 socket 文件,允许 Traefik 访问 Docker API,只读 - ./data/traefik.yml:/traefik.yml:ro # 挂载本地的 traefik.yml 配置文件到容器内,只读 - ./data/acme.json:/acme.json # 挂载本地的 acme.json 文件,存储 SSL 证书信息 - ./data/config.yml:/config.yml:ro # 可选的配置文件挂载路径,若需要可取消注释 labels: # 设置 Traefik 的相关标签,用于路由和中间件配置 - "traefik.enable=true" # 启用 Traefik 服务 - "traefik.http.routers.traefik.entrypoints=http" # 配置 HTTP 入口点 - "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_DASHBOARD_HOST}`)" # 定义 Traefik 仪表板的访问规则 - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}" # 为仪表板配置基本身份验证 - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https" # 配置 HTTP 到 HTTPS 的重定向 - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https" # 添加自定义请求头 - "traefik.http.routers.traefik.middlewares=traefik-https-redirect" # 将重定向中间件应用到 HTTP 路由 - "traefik.http.routers.traefik-secure.entrypoints=https" # 配置 HTTPS 入口点 - "traefik.http.routers.traefik-secure.rule=Host(`${TRAEFIK_DASHBOARD_HOST}`)" # 定义 HTTPS 路由的访问规则 - "traefik.http.routers.traefik-secure.middlewares=traefik-auth" # 为 HTTPS 路由应用基本身份验证中间件 - "traefik.http.routers.traefik-secure.tls=true" # 启用 TLS (HTTPS) - "traefik.http.routers.traefik-secure.tls.certresolver=${NS_Domain}" # 使用 DNS服务提供商 code 根据Traefik文档 选择你的服务提供商code - "traefik.http.routers.traefik-secure.tls.domains[0].main=${TLS_MAIN_DOMAIN}" # 定义主域名 - "traefik.http.routers.traefik-secure.tls.domains[0].sans=${TLS_SANS_DOMAIN}" # 定义子域名通配符 - "traefik.http.routers.traefik-secure.service=api@internal" # 使用 Traefik 内部 API 服务 networks: traefik-net: external: false # 使用外部定义的名为 proxy 的网络
|
.env
文件:
|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # .env 文件 # CF API CF_DNS_API_TOKEN = NS_Domain =cloudflare #根据你使用的DNS服务提供商 code 根据Traefik文档 选择你的服务提供商code # 设置环境变量,定义 Traefik 仪表板的凭据 ,默认账户名密码:admin TRAEFIK_DASHBOARD_CREDENTIALS =admin:$ $2y $ $05 $ $aOXINGgHfnZ //t.kUs7o9ej3faUbj2yNxc8k3WVrBybFOxxaTsLTe # Traefik Dashboard 域名 TRAEFIK_DASHBOARD_HOST =dash.docker.localhost # TLS 主域名和子域名 TLS_MAIN_DOMAIN =docker.localhost TLS_SANS_DOMAIN =*.docker.localhost
|
traefik.yml
文件:
|------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| api: dashboard: true # 启用 Traefik 的仪表板,可以通过指定的路由访问 debug: true # 启用调试模式,输出更多的日志信息 entryPoints: http: address: ":80" # 定义 HTTP 入口点,监听 80 端口 http: redirections: entryPoint: to: https # 重定向 HTTP 请求到 HTTPS scheme: https # 使用 HTTPS 作为重定向的目标协议 https: address: ":443" # 定义 HTTPS 入口点,监听 443 端口 serversTransport: insecureSkipVerify: true # 在与后端服务器通信时,跳过 TLS 证书验证(不推荐在生产环境中使用) providers: docker: endpoint: "unix:///var/run/docker.sock" # 指定 Docker API 的 socket 文件路径,Traefik 使用它来检测和管理 Docker 容器 exposedByDefault: false # 默认情况下,Docker 容器不会自动暴露给 Traefik,必须显式指定 watch: true file: filename: /config.yml # (已注释) 可选的文件提供者配置,用于从外部文件加载配置 watch: true # 允许 Traefik 自动监控和加载配置文件变化 certificatesResolvers: cloudflare: # 使用 DNS服务提供商 code 根据Traefik文档 选择你的服务提供商code acme: email: youremail@email.com # 申请 ACME 证书时使用的电子邮件地址 storage: acme.json # 存储证书信息的文件路径 # caServer: https://acme-v02.api.letsencrypt.org/directory # 正式环境的 Let's Encrypt 服务器 (默认) caServer: https://acme-staging-v02.api.letsencrypt.org/directory # 测试环境的 Let's Encrypt 服务器 (用于调试) dnsChallenge: provider: cloudflare # 使用 DNS服务提供商 code 根据Traefik文档 选择你的服务提供商code 进行 DNS 验证以获取证书 #disablePropagationCheck: true # (已注释) 如果通过 Cloudflare 获取证书有问题,可以取消注释此行以禁用传播检查 #delayBeforeCheck: 60s # (已注释) 如果需要确保 TXT 记录准备就绪,可以取消注释此行并设置检查延迟 resolvers: - "223.5.5.5:53" # AliDNS 解析器 - "119.29.29.29:53" # 备用 DNS 解析器 - "1.1.1.1" # 备用 DNS 解析器
|
config.yml
文件,可以选择配置,如果你宿主机有ng反代服务,你使用taerfik 的话会端口冲突,可以配置,但不过要把 docker-compose
和 Traefik
的配置文件注释去掉即可:
|---------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| http: #region routers routers: hexo: entryPoints: - "https" # 指定使用 HTTPS 入口点 rule: "Host(`hexo.docker.localhost`)" # 当访问的主机名为 hexo.local.shellscience.top 时,触发此路由 middlewares: - default-headers # 应用默认的安全头中间件 - https-redirectscheme # 应用 HTTPS 重定向中间件 tls: {} # 启用 TLS 加密 service: hexo # 指定将请求转发到名为 hexo 的服务 #region services services: hexo: loadBalancer: servers: - url: "http://127.0.0.1:5000" # 指定 Hexo 服务的后端服务器 URL passHostHeader: true # 传递原始的 Host 头信息到后端服务 #endregion middlewares: https-redirectscheme: redirectScheme: scheme: https # 将 HTTP 请求重定向为 HTTPS permanent: true # 使用永久重定向(HTTP 301) default-headers: headers: frameDeny: true # 禁止网页被嵌入到框架中,防止点击劫持攻击 browserXssFilter: true # 启用浏览器的 XSS 过滤器,增强安全性 contentTypeNosniff: true # 防止浏览器 MIME 类型嗅探 forceSTSHeader: true # 强制启用 HSTS(HTTP 严格传输安全) stsIncludeSubdomains: true # HSTS 规则应用于所有子域 stsPreload: true # 允许将域名加入 HSTS 预加载列表 stsSeconds: 15552000 # HSTS 头的有效期(秒),这里是 180 天 customFrameOptionsValue: SAMEORIGIN # 允许内容在同源的 iframe 中加载 customRequestHeaders: X-Forwarded-Proto: https # 设置 X-Forwarded-Proto 头为 https,用于指示原始请求协议 default-whitelist: ipAllowList: sourceRange: - "10.0.0.0/8" # 允许来自 10.0.0.0/8 网段的 IP 地址 - "192.168.0.0/16" # 允许来自 192.168.0.0/16 网段的 IP 地址 - "172.16.0.0/12" # 允许来自 172.16.0.0/12 网段的 IP 地址 secured: chain: middlewares: - default-whitelist # 应用默认的 IP 白名单中间件 - default-headers # 应用默认的安全头中间件
|
配置完毕我们 docker-compose up -d
如果配置没有问题你就可以通过你配置的域名成功访问 Traefik
的面板。
反代代理Dcoekr应用 {#反代代理Dcoekr应用}
这里拿 Memos
的程序来举例子:
下面是我的 Memos
的 docker-compose.yaml
文件,我们只需要把暴露的端口删除,添加 labels
标签以及下面几个配置(你想访问的域名、容器的端口、开启https、使用tls证书)以及让我们的程序接入 Traefik
的网络就好了。
|---------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| version: "3.0" services: memos: image: ghcr.io/usememos/memos:latest container_name: memos volumes: - ./data/:/var/opt/memos environment: - driver=sqlite labels: - "traefik.enable=true" - "traefik.http.routers.memos.rule=Host(`memos.local.com`)" - "traefik.http.services.memos.loadbalancer.server.port=<程序的端口>" - "traefik.http.routers.memos.entrypoints=https" - "traefik.http.routers.memos.tls=true" networks: - traefik-net networks: traefik-net: external: true
|
引用 {#引用}
Traefik
DNS服务提供文档: https://doc.traefik.io/traefik/https/acme/#providers
Traefik
Docker配置文档: https://doc.traefik.io/traefik/routing/providers/docker/
最后结尾的彩蛋 {#最后结尾的彩蛋}
找 DALL·E
生成了两张cover不过总感觉怪怪的,另外一张也放出来吧,有一种土拔鼠变成黄鼠狼的错觉。