一文搞定快速使用 Docker Compose 玩轉(zhuǎn) Traefik v2

前提條件
VPS 環(huán)境:海外??
Docker
有一個域名?
example.com使用?
cloudflare?管理域名的 DNS80/443?已打開
章節(jié)
Traefik 路由到 Docker 容器
Traefik 路由到本地 IP 地址
Traefik 中間件
Let's Encrypt 證書 HTTP challenge
Let's Encrypt 證書 DNS challenge
轉(zhuǎn)發(fā) HTTP 流量到 HTTPS
Traefik 路由到 Docker 容器

創(chuàng)建一個新的 docker 網(wǎng)絡(luò)
docker network create traefik_net
Traefik 和 containers(容器)需要在同一網(wǎng)絡(luò)上。Compose 會自動創(chuàng)建一個,但事實是隱藏的,以后可能會發(fā)生混亂。最好僅創(chuàng)建自己的網(wǎng)絡(luò)并將其設(shè)置為每個 compose 文件中的默認(rèn)網(wǎng)絡(luò)。
使用?docker network inspect traefik_net?查看連接到該網(wǎng)絡(luò)的容器
創(chuàng)建 traefik.yml
該文件包含所謂的靜態(tài) traefik 配置。
在此基本示例中,只有很少的關(guān)于 settings(設(shè)置)的解釋。
因為 exposedbydefault 被設(shè)置為 false,標(biāo)簽?"traefik.enable=true"?將需要用于應(yīng)該由 traefik 路由的容器。
這個文件將通過 bind mount 傳遞給 docker 容器,這將在我們?yōu)?traefik 使用 docker-compose.yml 時完成。
traefik.yml
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: true
dashboard: true
entryPoints:
web:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
稍后,當(dāng) traefik 容器運行時,使用命令?docker logs traefik, 檢查是否有提示:"Configuration loaded from file: /traefik.yml"。您不想成為對 traefik.yml 進(jìn)行更改的?moron,并且它什么也不做,因為實際上并未使用該文件。
創(chuàng)建?.env
它包含一些環(huán)境變量。
域名,API密鑰,IP地址,密碼…… 無論是針對一種情況的特定情況,還是針對另一種情況的不同情況,所有這些都理想地放在了這里。運行?docker-compose up?命令時,這些變量可用于 docker-compose。
這使得編寫文件可以更自由地從一個系統(tǒng)移動到另一個系統(tǒng),并且可以對?.env?文件進(jìn)行更改, 因此,在大型編寫文件或類似文件中忘記更改某些主機規(guī)則中的域名的錯誤可能性更小。
.env
MY_DOMAIN=example.com
DEFAULT_NETWORK=traefik_net
命令?docker-compose config?顯示了填充變量后的 compose 狀態(tài)。
這些變量僅在容器的初始構(gòu)建期間填寫。如果一個 env 變量也應(yīng)該在運行的容器中可用,則需要在 compose 文件的?environment?部分聲明它。
創(chuàng)建 traefik-docker-compose.yml
這是一個簡單的典型 compose 文件。
端口 80 已映射,因為我們希望 traefik 負(fù)責(zé)端口上的內(nèi)容-將其用作 entrypoint(入口點)。端口 8080 用于 traefik 顯示信息的儀表板。需要掛載 docker.sock,因此它實際上可以完成與 docker 交互的工作。?traefik.yml?的掛載是給出靜態(tài) traefik 配置的原因。默認(rèn)網(wǎng)絡(luò)被設(shè)置為第一步中創(chuàng)建的網(wǎng)絡(luò),因為它將在所有其他 compose 文件中設(shè)置。
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
networks:
default:
external:
name: $DEFAULT_NETWORK
運行 traefik-docker-compose.yml
docker-compose -f traefik-docker-compose.yml up -d?將會啟動 traefik 容器。
traefik 正在運行,您可以在 ip:8080 上檢查它,在那里您可以得到儀表板。
也可以用?docker logs traefik?檢查日志。
通常你會看到指南只有一個名為?docker-compose.yml?文件。其中包含多個服務(wù)/容器。然后只需?docker-compose up -d?就可以開始了。當(dāng)所有都是一個 compose 時,你甚至不需要費心去定義網(wǎng)絡(luò)。但這一次,我更喜歡在學(xué)習(xí)新東西時采取小而獨立的步驟。這就是為什么使用自定義命名的 docker-compose 文件,因為它允許更容易的分離。
您在教程中還可以看到?jīng)]有提及 traefik.yml,而東西只是使用 traefik 的命令或標(biāo)簽從 docker-compose 傳遞的。
如:?command: --api.insecure=true --providers.docker
但是這樣一來,組合文件看起來會更加混亂,您仍然無法從那里進(jìn)行任何操作,有時您仍然需要?traefik.yml。
所以...現(xiàn)在,使用結(jié)構(gòu)良好的可讀 traefik.yml
在 traefik 應(yīng)該路由的容器上添加標(biāo)簽
以下是 whoami,nginx,apache,portainer 的示例。
- "traefik.enable=true"
啟用 traefik
- "traefik.http.routers.whoami.entrypoints=web"
定義名為?whoami?的路由,該路由在入口點 Web(端口80)上偵聽
- "traefik.http.routers.whoami.rule=Host(
whoami.$MY_DOMAIN)"
定義此?whoami?路由規(guī)則,特別是當(dāng) url 等于?whoami.example.com(域名來自?.env?文件)時, 這意味著路由可以完成其工作并將其路由到服務(wù)。
不需要其他任何東西,traefik 可以從這些標(biāo)簽來自 docker 容器的上下文中了解其余信息。
whoami-docker-compose.yml
version: "3.7"
services:
whoami:
image: "containous/whoami"
container_name: "whoami"
hostname: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
networks:
default:
external:
name: $DEFAULT_NETWORK
nginx-docker-compose.yml
version: "3.7"
services:
nginx:
image: nginx:latest
container_name: nginx
hostname: nginx
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=web"
- "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
networks:
default:
external:
name: $DEFAULT_NETWORK
apache-docker-compose.yml
version: "3.7"
services:
apache:
image: httpd:latest
container_name: apache
hostname: apache
labels:
- "traefik.enable=true"
- "traefik.http.routers.apache.entrypoints=web"
- "traefik.http.routers.apache.rule=Host(`apache.$MY_DOMAIN`)"
networks:
default:
external:
name: $DEFAULT_NETWORK
portainer-docker-compose.yml
version: "3.7"
services:
portainer:
image: portainer/portainer
container_name: portainer
hostname: portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- portainer_data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=web"
- "traefik.http.routers.portainer.rule=Host(`portainer.$MY_DOMAIN`)"
networks:
default:
external:
name: $DEFAULT_NETWORK
volumes:
portainer_data:
運行容器
docker-compose -f whoami-docker-compose.yml up -d
docker-compose -f nginx-docker-compose.yml up -d
docker-compose -f apache-docker-compose.yml up -d
docker-compose -f portainer-docker-compose.yml up -d停止所有容器運行:docker stop $(docker ps -q)
Traefik 路由到本地 IP 地址
當(dāng) url 應(yīng)該瞄準(zhǔn)其他東西而不是 docker 容器。

定義 file provider,添加所需的路由和服務(wù)
所需要的是一個能夠捕獲某些 url 并將其路由到某些 IP 的 router。前面的示例顯示了如何在端口 80 上捕獲任何 url,但是沒有人告訴它在符合規(guī)則的情況下該怎么做。Traefik 只是知道,因為它是在容器的上下文中使用標(biāo)簽完成的, 而且由于 docker 在?traefik.yml?中被設(shè)置為提供程序。
對于這種 “在某些 IP 上發(fā)送流量”,需要 traefik 服務(wù), 并且要定義 traefik 服務(wù),需要一個新的提供程序, 即 file provider - 只是一個(fucking stupid)文件,告訴 traefik 該怎么做。
某種常見的做法是將?traefik.yml?本身設(shè)置為 file provider,以便進(jìn)行處理。
在提供者下有一個新的?file?部分,并設(shè)置了?traefik.yml?本身。
然后添加動態(tài)配置的東西。
一個名為?route-to-local-ip?的 router,有一個簡單的子域主機名規(guī)則。符合該規(guī)則(在本例中為確切的網(wǎng)址?test.example.com)的內(nèi)容將發(fā)送到 loadbalancer 服務(wù), 該服務(wù)會將其路由到特定的 IP 和特定的端口。
traefik.yml
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: true
dashboard: true
entryPoints:
web:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: "traefik.yml"
## DYNAMIC CONFIGURATION
http:
routers:
route-to-local-ip:
rule: "Host(`test.example.com`)"
service: route-to-local-ip-service
priority: 1000
entryPoints:
- web
services:
route-to-local-ip-service:
loadBalancer:
servers:
- url: "http://10.0.19.5:80"
路由的優(yōu)先級設(shè)置為 1000,這是一個非常高的值,超過了任何其他可能的路由。
不幸的是?.env?變量在這里不起作用,否則主機規(guī)則中的域名和 IP 將來自變量。因此,抬起頭來,您肯定會忘記更改這些。
運行 traefik-docker-compose
測試是否有效
docker-compose -f traefik-docker-compose.yml up -d
Traefik 中間件
任何容器的身份驗證中間件的示例。

創(chuàng)建一個新文件 users_credentials
包含 username:passwords 對,htpasswd?格式
在下面的示例中,密碼?krakatoa?設(shè)置為下面所有3個帳戶
users_credentials
me:$apr1$L0RIz/oA$Fr7c.2.6R1JXIhCiUI1JF0
admin:$apr1$ELgBQZx3$BFx7a9RIxh1Z0kiJG0juE/
bastard:$apr1$gvhkVK.x$5rxoW.wkw1inm9ZIfB0zs1
掛載 users_credentials
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./users_credentials:/users_credentials:ro"
networks:
default:
external:
name: $DEFAULT_NETWORK
在應(yīng)該進(jìn)行身份驗證的任何容器中添加兩個標(biāo)簽
第一個標(biāo)簽將名為?
auth-middleware?的新中間件附加到已存在的?whoami?路由器上。第二個標(biāo)簽為該中間件提供了 basicauth 類型,并告訴它用于認(rèn)證用戶的文件在哪里。
無需在此處安裝?users_credentials,它是 traefik 所需的文件, 這些標(biāo)簽是一種將信息傳遞給 traefik 的方式,它應(yīng)該在容器的上下文中進(jìn)行操作。
whoami-docker-compose.yml
version: "3.7"
services:
whoami:
image: "containous/whoami"
container_name: "whoami"
hostname: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
- "traefik.http.routers.whoami.middlewares=auth-middleware"
- "traefik.http.middlewares.auth-middleware.basicauth.usersfile=/users_credentials"
networks:
default:
external:
name: $DEFAULT_NETWORK
nginx-docker-compose.yml
version: "3.7"
services:
nginx:
image: nginx:latest
container_name: nginx
hostname: nginx
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=web"
- "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
- "traefik.http.routers.nginx.middlewares=auth-middleware"
- "traefik.http.middlewares.auth-middleware.basicauth.usersfile=/users_credentials"
networks:
default:
external:
name: $DEFAULT_NETWORK
運行容器,現(xiàn)在需要登錄名和密碼
docker-compose -f traefik-docker-compose.yml up -d
docker-compose -f whoami-docker-compose.yml up -d
docker-compose -f nginx-docker-compose.yml up -d
Let's Encrypt 證書,HTTP challenge

LE?- Let's Encrypt. 提供免費證書的服務(wù)Certificate?- 存儲在服務(wù)器文件中的加密密鑰,允許進(jìn)行加密通信并確認(rèn)身份ACME?- 一種協(xié)議(精確商定的通信方式),以協(xié)商來自 LE 的證書。它是 traefik 的一部分。DNS?- 互聯(lián)網(wǎng)上的服務(wù)器,將域名轉(zhuǎn)換為 IP 地址
Traefik 使用 ACME 向 LE 請求特定域的證書,如?example.com。LE 用一些隨機生成的文本來回答,然后 traefik 把這些文本放在服務(wù)器的特定位置。然后,LE 向 DNS 互聯(lián)網(wǎng)服務(wù)器詢問?example.com,結(jié)果指向了某個 IP 地址。LE 通過端口 80/443 查找該 IP 地址,查找包含該隨機文本的文件。
如果存在,那么這證明了要求證書的人都控制了服務(wù)器和域,因為它顯示了對 DNS 記錄的控制權(quán)。證書已頒發(fā),有效期為 3 個月,traefik 將在少于 30 天的時間內(nèi)自動嘗試?yán)m(xù)訂。
現(xiàn)在我們來看看該怎么做。
創(chuàng)建一個具有 600 權(quán)限的空 acme.json 文件
該文件將存儲證書以及有關(guān)證書的所有信息。
touch acme.json && chmod 600 acme.json
在 traefik.yml 中添加 443 入口點和證書解析器
在 entrypoint 部分中,新的 entrypoint 被添加為 websecure,端口 443
certificatesResolvers 是一個配置部分,它告訴 traefik 如何使用 acme resolver 獲取證書。
certificatesResolvers:
lets-encr:
acme:
#caServer: https://acme-staging-v02.api.letsencrypt.org/directory
storage: acme.json
email: [email protected]
httpChallenge:
entryPoint: web
解析器的名稱為?
lets-encr,并使用 acme注釋掉了 staging caServer 使 LE 頒發(fā)了一個 staging 證書,這是一個無效的證書,不會給綠鎖,但沒有限制,所以很適合測試。如果它在工作,它會說,我們加密。
Storage 告訴在哪里存儲給定的證書 -?
acme.json郵件是 LE 發(fā)送證書過期通知的地方
httpChallenge 有一個入口點,因此 acme 在端口 80 上執(zhí)行 http challenge
這就是 acme 所需要的一切
traefik.yml
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: true
dashboard: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
lets-encr:
acme:
#caServer: https://acme-staging-v02.api.letsencrypt.org/directory
storage: acme.json
email: [email protected]
httpChallenge:
entryPoint: web
暴露/映射端口 443 并將 acme.json 掛載在 traefik-docker-compose.yml 中
注意:acme.json 不是?:ro?- 只讀
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
env_file:
- .env
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
networks:
default:
external:
name: $DEFAULT_NETWORK
向容器添加所需的標(biāo)簽
與第一章中的純 HTTP 相比,它只是將路由器的入口點從?web?更改為?websecure, 并將名為?lets-encr?的證書解析器分配給現(xiàn)有路由器
whoami-docker-compose.yml
version: "3.7"
services:
whoami:
image: "containous/whoami"
container_name: "whoami"
hostname: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
- "traefik.http.routers.whoami.tls.certresolver=lets-encr"
networks:
default:
external:
name: $DEFAULT_NETWORK
nginx-docker-compose.yml
version: "3.7"
services:
nginx:
image: nginx:latest
container_name: nginx
hostname: nginx
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=websecure"
- "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
- "traefik.http.routers.nginx.tls.certresolver=lets-encr"
networks:
default:
external:
name: $DEFAULT_NETWORK
運行容器
稍等一分鐘
容器現(xiàn)在只能在 https 上工作并且具有 greenlock
檢查 acme.json 的內(nèi)容
如果要重新開始,請刪除acme.json
Let's Encrypt 證書在 cloudflare 上 DNS challenge

LE?- Let's Encrypt. 提供免費證書的服務(wù)Certificate?- 存儲在服務(wù)器文件中的加密密鑰,允許進(jìn)行加密通信并確認(rèn)身份ACME?- 一種協(xié)議(精確商定的通信方式),以協(xié)商來自 LE 的證書。它是 traefik 的一部分。DNS?- 互聯(lián)網(wǎng)上的服務(wù)器,將域名轉(zhuǎn)換為 IP 地址
Traefik 使用 ACME 向 LE 請求特定域的證書,如?example.com。LE 用一些隨機生成的文本來回答,然后 traefik 把這些文本放在服務(wù)器的特定位置。然后,LE 向 DNS 互聯(lián)網(wǎng)服務(wù)器詢問?example.com,結(jié)果指向了某個 IP 地址。LE 通過端口 80/443 查找該 IP 地址,查找包含該隨機文本的文件。
如果存在,那么這證明了要求證書的人都控制了服務(wù)器和域,因為它顯示了對 DNS 記錄的控制權(quán)。證書已頒發(fā),有效期為 3 個月,traefik 將在少于 30 天的時間內(nèi)自動嘗試?yán)m(xù)訂。
與 httpChallenge 相比的好處是能夠使用通配符證書。這些是驗證所有子域?*.example.com?的證書 另外,無需打開任何端口。
但 traefik 需要能夠?qū)?DNS 記錄進(jìn)行自動更改,因此需要管理網(wǎng)站 DNS 的人對此提供支持。這就是為什么選擇 cloudflare。
現(xiàn)在我們來看看該怎么做。為所有規(guī)劃的子域添加類型?A DNS 記錄
[whoami, nginx, *] 是示例子域,每個子域都應(yīng)有一個指向 traefik IP 的 A 記錄。
創(chuàng)建一個具有 600 權(quán)限的空 acme.json 文件
touch acme.json && chmod 600 acme.json
將 443 入口點和證書解析器添加到 traefik.yml
在 entrypoint 部分中,新的 entrypoint 被添加為 websecure,端口 443
certificatesResolvers 是一個配置部分,它告訴 traefik 如何使用 acme resolver 獲取證書。
certificatesResolvers:
lets-encr:
acme:
#caServer: https://acme-staging-v02.api.letsencrypt.org/directory
email: [email protected]
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
解析器的名稱為?
lets-encr,并使用 acme注釋掉了 staging caServer 使 LE 頒發(fā)了一個 staging 證書,這是一個無效的證書,不會給綠鎖,但沒有限制,所以很適合測試。如果它在工作,它會說,我們加密。
Storage 告訴在哪里存儲給定的證書 -?
acme.json郵件是 LE 發(fā)送證書過期通知的地方
dnsChallenge 是由一個?provider?指定的,
在這個例子中是 cloudflare。每個提供程序在 .env 文件中需要不同名稱的環(huán)境變量, 但這是稍后的內(nèi)容,這里只需要提供程序的名稱
解析器是在挑戰(zhàn)期間使用的知名 DNS 服務(wù)器的 IP
traefik.yml
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: true
dashboard: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
lets-encr:
acme:
#caServer: https://acme-staging-v02.api.letsencrypt.org/directory
email: [email protected]
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
在?.env?文件中添加所需的變量
我們知道根據(jù)支持的提供商列表添加哪些變量
對于 cloudflare 變量是
CF_API_EMAIL?- cloudflare loginCF_API_KEY?- global api key
.env
MY_DOMAIN=example.com
DEFAULT_NETWORK=traefik_net
[email protected]
CF_API_KEY=8d08c87dadb0f8f0e63efe84fb115b62e1abc
暴露/映射端口 443 并將 acme.json 掛載在 traefik-docker-compose.yml 中
注意:acme.json 不是?:ro?- 只讀
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
env_file:
- .env
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
networks:
default:
external:
name: $DEFAULT_NETWORK
在容器上添加所需的標(biāo)簽
與第一章中簡單的 http 相比
路由器的入口點從?
web?切換到?websecure分配給路由器的名為?
lets-encr?的證書解析器定義將要獲得證書的主域的標(biāo)簽,在這里是 whoami.example.com,域名是從?
.env?文件中提取的
whoami-docker-compose.yml
version: "3.7"
services:
whoami:
image: "containous/whoami"
container_name: "whoami"
hostname: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
- "traefik.http.routers.whoami.tls.certresolver=lets-encr"
- "traefik.http.routers.whoami.tls.domains[0].main=whoami.$MY_DOMAIN"
networks:
default:
external:
name: $DEFAULT_NETWORK
nginx-docker-compose.yml
version: "3.7"
services:
nginx:
image: nginx:latest
container_name: nginx
hostname: nginx
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=websecure"
- "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
- "traefik.http.routers.nginx.tls.certresolver=lets-encr"
- "traefik.http.routers.nginx.tls.domains[0].main=nginx.$MY_DOMAIN"
networks:
default:
external:
name: $DEFAULT_NETWORK
運行容器
docker-compose -f traefik-docker-compose.yml up -d
docker-compose -f whoami-docker-compose.yml up -d
docker-compose -f nginx-docker-compose.yml up -d
DNS 挑戰(zhàn)的全部重點就是獲取通配符!
很公平
因此,對于通配符,這些標(biāo)簽將加入 traefik compose。
與以前一樣使用相同的?
lets-encr?證書解析器,它在 traefik.yml 中定義子域(*.example.com)的通配符被設(shè)置為要獲取證書的主域
裸域(只是簡單的example.com)設(shè)置為sans(主題備用名稱)
同樣,您確實需要?* .example.com?和?example.com
在 DNS 控制面板中設(shè)置為 A 記錄,指向 traefik 的 IP
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
env_file:
- .env
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.tls.certresolver=lets-encr"
- "traefik.http.routers.traefik.tls.domains[0].main=*.$MY_DOMAIN"
- "traefik.http.routers.traefik.tls.domains[0].sans=$MY_DOMAIN"
networks:
default:
external:
name: $DEFAULT_NETWORK
現(xiàn)在,如果容器想作為子域進(jìn)行訪問,則只需要一個具有 url 規(guī)則的常規(guī)路由器,位于 443 端口入口點,并使用相同的?lets-encr?證書解析器
whoami-docker-compose.yml
version: "3.7"
services:
whoami:
image: "containous/whoami"
container_name: "whoami"
hostname: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
- "traefik.http.routers.whoami.tls.certresolver=lets-encr"
networks:
default:
external:
name: $DEFAULT_NETWORK
nginx-docker-compose.yml
version: "3.7"
services:
nginx:
image: nginx:latest
container_name: nginx
hostname: nginx
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=websecure"
- "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
- "traefik.http.routers.nginx.tls.certresolver=lets-encr"
networks:
default:
external:
name: $DEFAULT_NETWORK
這是apache,但這次運行在裸域?example.com?上
apache-docker-compose.yml
version: "3.7"
services:
apache:
image: httpd:latest
container_name: apache
hostname: apache
labels:
- "traefik.enable=true"
- "traefik.http.routers.apache.entrypoints=websecure"
- "traefik.http.routers.apache.rule=Host(`$MY_DOMAIN`)"
- "traefik.http.routers.apache.tls.certresolver=lets-encr"
networks:
default:
external:
name: $DEFAULT_NETWORK
轉(zhuǎn)發(fā) HTTP 流量到 HTTPS

http 停止使用 https 設(shè)置,最好將 http(80) 重定向到 https(443)。
Traefik 有專門的中間件 — redirectscheme。
當(dāng)?traefik.yml?本身設(shè)置為文件提供程序時,可以在動態(tài)部分的?traefik.yml?中的多個位置聲明此重定向。
或在任何正在運行的容器中使用標(biāo)簽,此示例在 traefik compose 中進(jìn)行操作。
使用 traefik 中的標(biāo)簽添加新路由和重定向方案
- "traefik.enable=true"
在這個 traefik 容器上啟用 traefik,不是說這里需要到服務(wù)的典型路由,而是說沒有它其他標(biāo)簽就不能工作
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
創(chuàng)建一個名為?redirect-to-https?的新中間件,輸入 “redirectscheme” 并為其分配方案?https。
- "traefik.http.routers.redirect-https.rule=hostregexp(`{host:.+}`)"
創(chuàng)建一個名為?redirect-https?的新路由,并使用一個正則表達(dá)式規(guī)則來捕獲所有傳入請求
- "traefik.http.routers.redirect-https.entrypoints=web"
聲明此路由器在哪個入口點上偵聽 - Web(端口80)
- "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
將新創(chuàng)建的 redirectscheme 中間件分配給此新創(chuàng)建的路由。
traefik-docker-compose.yml
version: "3.7"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
hostname: "traefik"
env_file:
- .env
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
labels:
- "traefik.enable=true"
## DNS CHALLENGE
- "traefik.http.routers.traefik.tls.certresolver=lets-encr"
- "traefik.http.routers.traefik.tls.domains[0].main=*.$MY_DOMAIN"
- "traefik.http.routers.traefik.tls.domains[0].sans=$MY_DOMAIN"
## HTTP REDIRECT
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.redirect-https.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirect-https.entrypoints=web"
- "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
networks:
default:
external:
name: $DEFAULT_NETWORK
優(yōu)點知識春節(jié)課程特惠活動?

?點擊屏末?|?閱讀原文?|?即刻學(xué)習(xí)