Traefik 搭配 Docker 自動更新 Let’s Encrypt 憑證

Traefik 搭配 Docker 自動更新 Let’s Encrypt 憑證
Traefik 搭配 Docker 自動更新 Let’s Encrypt 憑證

之前寫過蠻多篇 Let’s Encrypt 的使用教學 ,但是這次要跟大家介紹一套非常好用的工具 Traefik 搭配自動化更新 Let’s Encrypt 憑證,為什麼會推薦 Traefik 呢,原因在於 Traefik 可以自動偵測 Docker 容器內的 Label 設置,並且套用設置在 Traefik 服務內,也就是隻要修改服務的 docker-compose 內容,重新啟動,Traefik 就可以抓到新的設置。這點在其它工具像是 NginxCaddy 是無法做到的。底下我們來一步一步教大家如何設置啟用前後端服務。全部代碼都放在 GitHub 上面 了。

教學影片

啟動 Traefik 服務

在啟動 Traefik 服務前,需要創建一個獨立的 Docker 網絡,請在 Host 內下

$ docker network create web

接着創建 Traefik 設置檔存放目錄 /opt/traefik 此目錄自由命名。

$ mkdir -p /opt/traefik

接着在此目錄底下創建三個文件

$ touch /opt/traefik/docker-compose.yml
$ touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.json
$ touch /opt/traefik/traefik.toml

其中 docker-compose.yml 用來啟動 Traefik 服務, acme.json 則是存放 Let’s Encrypt 的憑證,此文件權限必須為 600 ,最後則是 traefik 設置檔 traefik.toml 。一一介紹這些文件的內容,底下是 docker-compose.yml

version: '2'

services:
  traefik:
    image: traefik
    restart: always
    ports:
      - 80:80
      - 443:443
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/traefik/traefik.toml:/traefik.toml
      - /opt/traefik/acme.json:/acme.json
    container_name: traefik

networks:
  web:
    external: true

此文件必須要由 root 用户來運行,原因是要 Listen 80 及 443 連接端口,其中 acme.json 及 traefik.toml 則由 host 文件直接掛載進容器內。接着看 traefik.toml

debug = false

logLevel = "INFO"
defaultEntryPoints = ["https","http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]

[acme]
email = "xxxxx@gmail.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true

[acme.httpChallenge]
entryPoint = "http"

[docker]
endpoint = "unix:///var/run/docker.sock"
watch = true

其中 onHostRule 用於讀取 docker container 內的 frontend.ruleHost 設置,這樣才可以跟 Let’s Encrypt 申請到憑證。最後啟動步驟

$ cd /opt/traefik
$ docker-compose up -d

啟動 App 服務

請打開 docker-compose.yml 文件

version: '3'

services:
  app_1:
    image: appleboy/test:alpine
    restart: always
    networks:
      - web
    logging:
      options:
        max-size: "100k"
        max-file: "3"
    labels:
      - "traefik.docker.network=web"
      - "traefik.enable=true"
      - "traefik.basic.frontend.rule=Host:demo1.ggz.tw"
      - "traefik.basic.port=8080"
      - "traefik.basic.protocol=http"

  app_2:
    image: appleboy/test:alpine
    restart: always
    networks:
      - web
    logging:
      options:
        max-size: "100k"
        max-file: "3"
    labels:
      - "traefik.docker.network=web"
      - "traefik.enable=true"
      - "traefik.basic.frontend.rule=Host:demo2.ggz.tw"
      - "traefik.basic.port=8080"
      - "traefik.basic.protocol=http"

networks:
  web:
    external: true

可以看到透過 docker labels 設置讓 traefik 直接讀取並且套用設置。啟動服務後可以看到 acme.json 已經存放了各個 host 的憑證信息,未來只要將此文件備份,就可以不用一直申請了。最後用 curl 來測試看看

Traefik 搭配 Docker 自動更新 Let’s Encrypt 憑證
Traefik 搭配 Docker 自動更新 Let’s Encrypt 憑證

心得

由於 Traefik 可以自動讀取 docker label 內容,未來只需要維護 App 的 docker-compose 文件,對於部署上面相當方便啊,透過底下指令就可以重新啟動容器設置

$ docker-compose up -d --force-recreate --no-deps app

如果對於自動化部署有興趣,可以參考我在 Udemy 上的在線課程