使用 Traefik 進行 HTTP 路由
引言
在本地開發期間,通常需要執行多個 HTTP 服務。您可能同時擁有 API 和前端應用程式、用於模擬資料端點的 WireMock 服務,或者資料庫視覺化工具(例如 phpMyAdmin 或 pgAdmin)。在許多開發環境中,這些服務暴露在不同的埠上,這需要您記住每個埠上是什麼,但也會引入其他問題(例如 CORS)。
透過充當唯一的暴露服務,然後根據請求 URL(透過路徑或主機名)將請求路由到適當的服務,反向代理可以極大地簡化此設定。Traefik 是一個現代的雲原生反向代理和負載均衡器,它可以使開發和部署多服務應用程式變得更加容易。本指南將向您展示如何將 Traefik 與 Docker 配合使用來增強您的開發環境。
在本指南中,您將學習如何
- 使用 Docker 啟動 Traefik
- 配置路由規則以在兩個容器之間分流流量
- 在容器化開發環境中使用 Traefik
- 使用 Traefik 將請求傳送到非容器化工作負載
先決條件
按照本操作指南進行操作需要滿足以下先決條件
- Docker Desktop
- Node.js 和 yarn
- Docker 基礎知識
將 Traefik 與 Docker 配合使用
Traefik 的獨特功能之一是它可以透過多種方式進行配置。當使用 Docker 提供程式時,Traefik 使用 labels 從其他正在執行的容器獲取其配置。Traefik 會監聽引擎事件(用於容器啟動和停止),提取 labels,並更新其配置。
雖然有 許多 Traefik 監控的 labels,但最常用的兩個是
traefik.http.routers.<service-name>.rule
- 用於指示路由規則(在此處檢視所有可用規則)traefik.http.services.<service-name>.loadbalancer.server.port
- 指示 Traefik 應該將請求轉發到的埠。請注意,此容器埠無需在您的主機上暴露(在此處閱讀有關埠檢測的資訊)
我們來快速演示如何啟動 Traefik,然後配置另外兩個容器,使其可以使用不同的主機名進行訪問。
為了使兩個容器能夠相互通訊,它們需要位於同一個網路上。使用
docker network create
命令建立一個名為traefik-demo
的網路$ docker network create traefik-demo
使用以下命令啟動一個 Traefik 容器。該命令將 Traefik 暴露在埠 80,掛載 Docker socket(用於監控容器以更新配置),並傳遞
--providers.docker
引數來配置 Traefik 使用 Docker 提供程式。$ docker run -d --network=traefik-demo -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik:v3.1.2 --providers.docker
現在,啟動一個簡單的 Nginx 容器,並定義 Traefik 用於配置 HTTP 路由的 labels。請注意,此 Nginx 容器未暴露任何埠。
$ docker run -d --network=traefik-demo --label 'traefik.http.routers.nginx.rule=Host(`nginx.localhost`)' nginx
容器啟動後,開啟瀏覽器訪問 http://nginx.localhost 檢視應用程式(所有基於 Chromium 的瀏覽器都會將 *.localhost 請求本地路由,無需額外設定)。
啟動第二個將使用不同主機名的應用程式。
$ docker run -d --network=traefik-demo --label 'traefik.http.routers.welcome.rule=Host(`welcome.localhost`)' docker/welcome-to-docker
容器啟動後,開啟瀏覽器訪問 http://welcome.localhost。您應該會看到一個“歡迎使用 Docker”的網站。
在開發中使用 Traefik
既然您已經體驗了 Traefik,是時候嘗試在開發環境中使用它了。在本例中,您將使用一個具有分離前端和後端的示例應用程式。該應用程式堆疊具有以下配置:
- 所有發往 /api 的請求都轉到 API 服務
- 所有發往 localhost 的其他請求都轉到前端客戶端
- 由於應用程式使用 MySQL,db.localhost 應該提供 phpMyAdmin,以便在開發期間輕鬆訪問資料庫


該應用程式可以在 GitHub 上訪問:dockersamples/easy-http-routing-with-traefik。
在
compose.yaml
檔案中,Traefik 使用以下配置:services: proxy: image: traefik:v3.1.2 command: --providers.docker ports: - 80:80 volumes: - /var/run/docker.sock:/var/run/docker.sock
請注意,這本質上與之前使用的配置相同,但現在是 Compose 語法。
客戶端服務具有以下配置,它將啟動容器併為其提供 labels,以便在 localhost 接收請求。
services: # … client: image: nginx:alpine volumes: - "./client:/usr/share/nginx/html" labels: traefik.http.routers.client.rule: "Host(`localhost`)"
api 服務具有類似的配置,但您會注意到路由規則有兩個條件:主機必須是“localhost”,並且 URL 路徑必須帶有“/api”字首。由於此規則更具體,Traefik 將優先於客戶端規則對其進行評估。
services: # … api: build: ./dev/api volumes: - "./api:/var/www/html/api" labels: traefik.http.routers.api.rule: "Host(`localhost`) && PathPrefix(`/api`)"
最後,
phpmyadmin
服務配置為接收主機名“db.localhost”的請求。該服務還定義了環境變數以自動登入,從而使進入應用程式變得更容易一些。services: # … phpmyadmin: image: phpmyadmin:5.2.1 labels: traefik.http.routers.db.rule: "Host(`db.localhost`)" environment: PMA_USER: root PMA_PASSWORD: password
在啟動堆疊之前,如果 Nginx 容器仍在執行,請將其停止。
就是這樣了。現在,您只需要使用 docker compose up
命令啟動 Compose 堆疊,所有服務和應用程式即可進行開發。
將流量傳送到非容器化工作負載
在某些情況下,您可能希望將請求轉發到未在容器中執行的應用程式。在下面的架構圖中,使用了與之前相同的應用程式,但 API 和 React 應用程式現在在本機主機上執行。


為此,Traefik 需要使用另一種方法來配置自己。File provider 允許您在 YAML 文件中定義路由規則。這是一個示例檔案:
http:
routers:
native-api:
rule: "Host(`localhost`) && PathPrefix(`/api`)"
service: native-api
native-client:
rule: "Host(`localhost`)"
service: native-client
services:
native-api:
loadBalancer:
servers:
- url: "http://host.docker.internal:3000/"
native-client:
loadBalancer:
servers:
- url: "http://host.docker.internal:5173/"
此配置表明,針對 localhost/api
的請求將被轉發到名為 native-api
的服務,該服務然後將請求轉發到 http://host.docker.internal:3000。主機名 host.docker.internal
是 Docker Desktop 提供的一個名稱,用於將請求傳送到主機。
使用此檔案,唯一的更改是 Traefik 的 Compose 配置。具體有兩處更改:
- 配置檔案被掛載到 Traefik 容器中(具體的目的地路徑由您決定)
command
命令更新為新增 file provider 並指向配置檔案的位置
services:
proxy:
image: traefik:v3.1.2
command: --providers.docker --providers.file.filename=/config/traefik-config.yaml --api.insecure
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./dev/traefik-config.yaml:/config/traefik-config.yaml
啟動示例應用程式
要執行將 Traefik 的請求轉發到本機執行應用程式的示例應用程式,請使用以下步驟:
如果您的 Compose 堆疊仍在執行,請使用以下命令將其停止:
$ docker compose down
使用提供的
compose-native.yaml
檔案啟動應用程式$ docker compose -f compose-native.yaml up
開啟 https:// 將返回 502 Bad Gateway 錯誤,因為其他應用程式尚未執行。
透過執行以下步驟啟動 API:
cd api yarn install yarn dev
在新的終端視窗中執行以下步驟啟動前端(從專案根目錄開始)
cd client yarn install yarn dev
在 https:// 開啟應用程式。您應該會看到一個從 https:///api/messages 獲取訊息的應用程式。您也可以開啟 http://db.localhost 直接從 Mongo 資料庫檢視或調整可用訊息。Traefik 將確保請求被正確路由到相應的容器或應用程式。
完成後,執行
docker compose down
停止容器,並透過按ctrl+c
停止 Yarn 應用程式。
總結
執行多個服務不再需要複雜的埠配置和良好的記憶力。藉助 Traefik 等工具,您可以輕鬆啟動所需的服務並輕鬆訪問它們——無論是應用程式本身(如前端和後端)還是額外的開發工具(如 phpMyAdmin)。