こんにちは。nginx-proxyとacme-companionで構成していたリバースプロキシを、前から気になっていたTraefikに移行してみました。
nginx-proxyの構成について
現在は以下のdocker-compose.yml
で示すような構成でした。
他のdocker-compose.yml
で作成したコンテナを参加させられるように、既定のネットワークは使わずにnginx-proxy
という名前のネットワークを作成しています。
# nginx-proxy/docker-compose.yml
# 参考: https://github.com/nginx-proxy/acme-companion/blob/main/docs/Docker-Compose.md
version: "3.9"
services:
nginx-proxy:
image: "nginxproxy/nginx-proxy"
container_name: "nginx-proxy"
environment:
DHPARAM_GENERATION: "false"
networks: ["nginx-proxy"]
ports: ["80:80", "443:443"]
restart: "always"
volumes:
- "/var/run/docker.sock:/tmp/docker.sock:ro"
# nginx-proxy
- "certs:/etc/nginx/certs"
- "dhparam:/etc/nginx/dhparam"
- "vhost:/etc/nginx/vhost.d"
# acme-companion
- "html:/usr/share/nginx/html"
acme-companion:
image: "nginxproxy/acme-companion"
container_name: "acme-companion"
depends_on: ["nginx-proxy"]
environment:
DEFAULT_EMAIL: "master@mail.example.com"
networks: ["nginx-proxy"]
restart: "always"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "acme:/etc/acme.sh"
volumes_from: ["nginx-proxy"]
networks:
nginx-proxy:
name: "nginx-proxy"
volumes:
# nginx-proxy
certs:
name: "nginx-proxy-certs"
dhparam:
name: "nginx-proxy-dhparam"
vhost:
name: "nginx-proxy-vhost"
# acme-companion
acme:
name: "acme-companion-acme"
html:
name: "acme-companion-html"
WordPress等のコンテナをリバースプロキシの対象にするには、nginx-proxy
ネットワークに参加させます。
# wordpress-nginx-proxy/docker-compose.yml
# ※データベースコンテナなどの無関係な部分は省略しています。
services:
wordpress:
environment:
LETSENCRYPT_HOST: "www.example.com,example.com"
VIRTUAL_HOST: "www.example.com,example.com"
networks: ["default", "nginx-proxy"]
networks:
default:
name: www-example-com
nginx-proxy:
external: true
name: "nginx-proxy"
Traefikの構成について
Traefikを実行するためのdocker-compose.yml
は次のようになりました。
基本的な使い道はnginx-proxyの時と同じで、リバースプロキシを使いたいコンテナをtraefik
ネットワークに参加させて、ドメイン等の設定をします。
特筆すべきところとして、--providers.docker.exposedByDefault=false
を指定していない状態で尚且つLet's Encryptの設定をしていると、起動時に無効なドメインでLet's Encryptしまくってリクエストレート上限に引っかかるので注意しましょう。
# traefik/docker-compose.yml
version: "3.9"
services:
traefik:
image: "traefik:3.0"
container_name: "traefik"
command:
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false" # `traefik.enable=true`を指定したコンテナのみ対象にする。
- "--providers.docker.network=traefik" # 対象とするネットワークを明示的に指定する。
# `http`エントリポイントの設定をする。
- "--entryPoints.http.address=:80"
- "--entryPoints.http.http.redirections.entryPoint.permanent=true"
- "--entryPoints.http.http.redirections.entryPoint.scheme=https"
- "--entryPoints.http.http.redirections.entryPoint.to=https"
# `https`エントリポイントの設定をする。
- "--entryPoints.https.address=:443"
- "--entryPoints.https.http.tls.certResolver=letsencrypt"
# `letsencrypt`証明書リゾルバにLet's Encryptの設定をする。
- "--certificatesResolvers.letsencrypt.acme.email=master@mail.example.com"
- "--certificatesResolvers.letsencrypt.acme.httpChallenge.entrypoint=http"
- "--certificatesResolvers.letsencrypt.acme.storage=acme.json"
networks: ["traefik"]
ports: ["80:80", "443:443"]
restart: "always"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./acme.json:/acme.json"
networks:
traefik:
name: "traefik"
同じように、wordpress
コンテナをtraefik
ネットワークに参加させて諸々の設定をしています。
# wordpress-traefik/docker-compose.yml
# ※データベースコンテナなどの無関係な部分は省略しています。
services:
wordpress:
labels:
- "traefik.enable=true"
- "traefik.http.routers.www-example-com.rule=Host(`www.example.com`) || Host(`example.com`)"
- "traefik.http.routers.www-example-com.tls=true"
- "traefik.http.routers.www-example-com.tls.certResolver=letsencrypt"
networks: ["default", "traefik"]
networks:
default:
name: "www-example-com"
traefik:
external: true
name: "traefik"
感想
この項は『解説』にしようと思っていたのですが、表題の移行作業だけだと解説すべき箇所が無かったので感想になりました。
逆に言えば、Traefikはそれくらいシンプルで洗練された仕組みを提供しているので、Traefikに興味が出た方はぜひ導入してみてください。