プッシュ通知
新記事をすぐにお知らせ
Dokku上でマルチドメイン・マルチサービスを運用する場合、TraefikはnginxからのHTTPS・ルーティング管理を劇的にシンプル化します。アプリにラベルを付けるだけで自動HTTPS取得・ルーティング・負荷分散が完成し、運用負荷を大幅に軽減できる実践的なアプローチです。
Dokkuを使ってAPIやWebアプリケーションをセルフホストしている開発者の多くは、最初の1〜2個のサービス公開までは、Dokku標準のnginxプラグインで十分と感じています。しかし、サービスが増えていくにつれて、以下のような課題が顕在化してきます。
Dokku標準のnginxはテンプレートベースで自動生成されますが、カスタム要件(Basic認証、特定パスのリダイレクト、ヘッダ付与など)が増えると、/home/dokku/<app>/nginx.conf.d/ に手動で設定を追加する必要が出てきます。アプリが5個、10個と増えていくと、nginx.confの総行数は数百行を超え、どのブロックがどのアプリに対応しているのか追跡が困難になります。
Dokku標準のdokku-letsencryptプラグインは単一ドメインの証明書更新には優秀ですが、複数のサブドメイン(api.example.com、admin.example.com、app.example.comなど)を管理する場合、各ドメインの証明書更新タイミングが異なり、更新失敗時の対応も煩雑になります。
新しいAPIやサービスを追加するたびに、以下の作業が必要になります:
このプロセスは手作業が多く、typoやコンフリクトのリスクが高まります。
nginxの設定ファイルにsyntax errorがあると、nginx -tで検出されても、その原因特定と修正に時間がかかります。特に複数のlocationブロックが絡み合っている場合、予期しない動作が起きることもあります。
TraefikはGoで実装された次世代のリバースプロキシで、Dockerコンテナに付与したラベルを読み取り、動的にルーティング設定を生成します。Dokku環境では、Traefikプラグインを導入することで、nginxの複雑な設定管理から完全に解放されます。
1. ラベルベースのルーティング定義
nginxのserverブロックやlocationディレクティブを書く代わりに、Dokkuアプリにtraefik.*という環境変数(またはラベル)を付与するだけで、ルーティングが完成します。
dokku config:set my-api \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_MYAPI_RULE='Host(`api.example.com`)' \
TRAEFIK_HTTP_ROUTERS_MYAPI_ENTRYPOINTS=websecure \
TRAEFIK_HTTP_ROUTERS_MYAPI_TLS=true
この数行で、nginxなら30〜50行かかる設定が完成します。
2. Let’s Encryptの完全自動化
Traefikに組み込まれたACME(Automated Certificate Management Environment)機能により、ホスト名ごとに自動的にLet’s Encrypt証明書を取得・更新します。DNS-01検証を使えば、Route53などのDNSプロバイダと連携して、ワイルドカード証明書も自動取得可能です。
3. 動的なサービスディスカバリ
Dokkuアプリをデプロイしてラベルを追加するだけで、Traefikが自動的にそれを検出し、ルーティングテーブルに追加します。設定ファイルのリロード、nginx再起動といった手作業が一切不要です。
Dokku + Traefik構成を図式化すると、以下のようになります。
インターネット
↓
[80/443ポート]
↓
┌─────────────────────┐
│ Traefik Container │
│ (リバースプロキシ) │
│ - ルーティング │
│ - HTTPS/TLS │
│ - Let's Encrypt │
└─────────────────────┘
↓ ↓ ↓
┌────────────────────────────────────────┐
│ Dokku Host (Docker) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ my-api │ │ my-admin │ │
│ │ (Port 5000) │ │ (Port 3000) │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ 各アプリにTraefik用ラベルが付与 │
│ → Traefikが自動検出・ルーティング │
└────────────────────────────────────────┘
フロー詳細:
https://api.example.com/usersにアクセスHost(api.example.com)というルールにマッチするルーターを検索my-apiサービス(Port 5000)を指しているため、そこへプロキシmy-apiコンテナが/usersエンドポイントを処理して応答この一連の流れで、nginxの設定ファイルは一切必要ありません。
本記事の手順を実行するには、以下の環境が必要です。
dokku versionコマンドで確認可能な状態# Dokkuのバージョン確認
dokku version
# Dockerの動作確認
docker ps
# ホストのポート確認(80/443が使用されていないこと)
sudo netstat -tlnp | grep -E ':(80|443)'
TraefikをDokku環境の唯一のリバースプロキシにするため、まずDokku標準のnginxを無効化する必要があります。
Dokku標準のnginxとTraefik両方が同時に80/443ポートをlistenしようとすると、ポート競合エラーが発生し、どちらも正常に起動できません。Traefik導入時は、ホストの80/443をTraefikに一本化するのがベストプラクティスです。
# Dokku標準のnginx-vhostsプラグインを無効化
dokku plugin:disable nginx-vhosts
# Dokku標準のLet's Encryptプラグインも無効化
# (Traefik側のACMEで証明書管理を一元化するため)
dokku plugin:disable letsencrypt
# 確認:プラグインが無効化されたことを確認
dokku plugin:list
既にDokku上で稼働しているアプリがある場合、この操作により一時的にHTTPアクセスが遮断されます。本番環境で実施する場合は、メンテナンス時間を事前に告知し、実施してください。
Dokku用のTraefikプラグインをインストールします。
# Dokkuプラグインディレクトリに移動
cd /var/lib/dokku/plugins
# Traefikプラグインをクローン
sudo git clone https://github.com/dokku-community/dokku-traefik.git traefik
# プラグインをインストール
dokku plugin:install
# インストール確認
dokku traefik:version
# Traefikプラグインのサブコマンドを確認
dokku traefik:help
# 出力例:
# traefik:disable Disable traefik
# traefik:enable Enable traefik
# traefik:logs Show traefik logs
# traefik:set Set traefik configuration
# ...
TraefikがLet’s Encryptから自動的に証明書を取得できるよう、ACME(Automated Certificate Management Environment)を設定します。
Let’s Encryptは、証明書の有効期限が近づくと、設定したメールアドレスに通知を送ります。
# グローバル設定としてACMEメールを設定
dokku config:set --global \
TRAEFIK_ACME_EMAIL=your-email@example.com
Let’s Encryptにはレートリミット(1時間に5回まで)があり、設定ミスで何度も失敗するとブロックされます。本番前に必ずステージング環境でテストしてください。
# ステージング環境(テスト用、自己署名証明書)を使用
dokku config:set --global \
TRAEFIK_ACME_CA_SERVER=https://acme-staging-v02.api.letsencrypt.org/directory
証明書メタデータを保存するファイルのパスを指定します。
# ストレージパスを設定
dokku config:set --global \
TRAEFIK_ACME_STORAGE=/var/lib/traefik/acme.json
# ストレージディレクトリを作成
sudo mkdir -p /var/lib/traefik
sudo touch /var/lib/traefik/acme.json
# パーミッション設定(Traefikが読み書きできるように)
sudo chmod 600 /var/lib/traefik/acme.json
sudo chown 1000:1000 /var/lib/traefik/acme.json # Traefikコンテナのユーザに合わせる
Let’s Encryptの検証方式として、HTTP-01(ポート80でのチャレンジ)を使用します。
# HTTP-01チャレンジを有効化
dokku config:set --global \
TRAEFIK_ACME_HTTP_ENTRYPOINT=web
複数のサブドメインやワイルドカード証明書を取得する場合、DNS-01検証が便利です。Route53と連携するための設定を行います。
AWS管理コンソールでIAMユーザを作成し、Route53への最小権限を付与します。
推奨IAMポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/Z1234567890ABC"
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets"
],
"Resource": "*"
}
]
}
※ Z1234567890ABCは自分のHosted Zone IDに置き換えてください。
IAMユーザに対してAccess Key IDとSecret Access Keyを発行します。
# AWS CLI で確認(オプション)
aws iam list-access-keys --user-name traefik-user
発行したAWSの認証情報をDokku経由でTraefikに注入します。
# AWS認証情報をグローバル設定として登録
dokku config:set --global \
AWS_ACCESS_KEY_ID=AKIA... \
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxx \
AWS_REGION=us-east-1
# DNS-01プロバイダとしてRoute53を指定
dokku config:set --global \
TRAEFIK_ACME_DNS_CHALLENGE_PROVIDER=route53
DNS-01検証では、TXTレコードの反映を待つ必要があります。環境によっては反映に時間がかかるため、タイムアウト値を調整します。
# DNS反映待ちタイムアウトを120秒に設定
dokku config:set --global \
LEGO_DNS_TIMEOUT=120
ここまでの設定を反映させて、Traefikコンテナを起動します。
# Traefikを有効化・起動
dokku traefik:enable
dokku traefik:start
# 起動確認
dokku traefik:info
# Traefikのログを確認
dokku traefik:logs
# 出力例:
# time="2025-12-10T08:19:13Z" level=info msg="Traefik version 3.0.0"
# time="2025-12-10T08:19:14Z" level=info msg="Starting Traefik"
# ...
# Traefikが80/443をlistenしていることを確認
sudo netstat -tlnp | grep -E ':(80|443)'
# 出力例:
# tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1234/traefik
# tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1234/traefik
それでは、実際にDokkuアプリをTraefik経由で公開してみましょう。最初の例は、REST APIをapi.example.comで公開するケースです。
# アプリを作成
dokku apps:create my-api
# 環境変数を設定(アプリ側の設定)
dokku config:set my-api \
NODE_ENV=production \
PORT=5000
# Gitリモートを追加
git remote add dokku dokku@your-server:my-api
# コードをpush(自動デプロイ)
git push dokku main:master
# Traefik用ラベルを環境変数として設定
dokku config:set my-api \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_MYAPI_RULE='Host(`api.example.com`)' \
TRAEFIK_HTTP_ROUTERS_MYAPI_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_MYAPI_TLS=true \
TRAEFIK_HTTP_ROUTERS_MYAPI_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_MYAPI_LOADBALANCER_SERVER_PORT=5000
Route53またはお使いのDNSプロバイダで、api.example.comがDokkuサーバのIPアドレスを指していることを確認してください。
# DNS確認コマンド例
dig api.example.com
# 出力例:
# api.example.com. 300 IN A 203.0.113.42
# HTTPでアクセス(自動的にHTTPSにリダイレクト)
curl -I http://api.example.com/
# 出力例:
# HTTP/1.1 301 Moved Permanently
# Location: https://api.example.com/
# HTTPSでアクセス
curl -I https://api.example.com/
# 出力例:
# HTTP/2 200
# content-type: application/json
次に、複数のサブドメインで異なるサービスを公開する、より実践的なシナリオを見てみましょう。
# REST API
dokku apps:create my-api
dokku config:set my-api PORT=5000
# 管理画面
dokku apps:create my-admin
dokku config:set my-admin PORT=3000
# フロントエンド
dokku apps:create my-frontend
dokku config:set my-frontend PORT=8080
my-api(api.example.com):
dokku config:set my-api \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_API_RULE='Host(`api.example.com`)' \
TRAEFIK_HTTP_ROUTERS_API_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_API_TLS=true \
TRAEFIK_HTTP_ROUTERS_API_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_SERVER_PORT=5000
my-admin(admin.example.com):
dokku config:set my-admin \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_ADMIN_RULE='Host(`admin.example.com`)' \
TRAEFIK_HTTP_ROUTERS_ADMIN_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_ADMIN_TLS=true \
TRAEFIK_HTTP_ROUTERS_ADMIN_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_ADMIN_LOADBALANCER_SERVER_PORT=3000
my-frontend(app.example.com):
dokku config:set my-frontend \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_FRONTEND_RULE='Host(`app.example.com`)' \
TRAEFIK_HTTP_ROUTERS_FRONTEND_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_FRONTEND_TLS=true \
TRAEFIK_HTTP_ROUTERS_FRONTEND_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_FRONTEND_LOADBALANCER_SERVER_PORT=8080
# 各アプリの設定を確認
dokku config my-api | grep TRAEFIK
dokku config my-admin | grep TRAEFIK
dokku config my-frontend | grep TRAEFIK
Traefikに組み込まれたダッシュボードを有効化すると、設定されたルーターやサービスを視覚的に確認できます。
# ダッシュボードを有効化(オプション)
dokku config:set --global \
TRAEFIK_API_DASHBOARD=true \
TRAEFIK_API_INSECURE=false
# ダッシュボードURL(例)
# https://traefik.example.com/dashboard/
同じドメイン(例:example.com)で異なるパスをそれぞれ別のアプリに振り分ける場合の設定方法です。
https://example.com/api → my-api(ポート5000)
https://example.com/admin → my-admin(ポート3000)
https://example.com/ → my-frontend(ポート8080)
# API(/api で始まるパス)
dokku config:set my-api \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_API_RULE='Host(`example.com`) && PathPrefix(`/api`)' \
TRAEFIK_HTTP_ROUTERS_API_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_API_TLS=true \
TRAEFIK_HTTP_ROUTERS_API_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_SERVER_PORT=5000 \
TRAEFIK_HTTP_MIDDLEWARES_API_STRIPPREFIX_PREFIXES='/api'
# 管理画面(/admin で始まるパス)
dokku config:set my-admin \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_ADMIN_RULE='Host(`example.com`) && PathPrefix(`/admin`)' \
TRAEFIK_HTTP_ROUTERS_ADMIN_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_ADMIN_TLS=true \
TRAEFIK_HTTP_ROUTERS_ADMIN_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_ADMIN_LOADBALANCER_SERVER_PORT=3000 \
TRAEFIK_HTTP_MIDDLEWARES_ADMIN_STRIPPREFIX_PREFIXES='/admin'
# フロントエンド(ルートパス)
dokku config:set my-frontend \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_FRONTEND_RULE='Host(`example.com`)' \
TRAEFIK_HTTP_ROUTERS_FRONTEND_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_FRONTEND_TLS=true \
TRAEFIK_HTTP_ROUTERS_FRONTEND_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_FRONTEND_LOADBALANCER_SERVER_PORT=8080
TRAEFIK_HTTP_MIDDLEWARES_API_STRIPPREFIX_PREFIXES='/api'は、Traefikがアプリにリクエストを転送する際に、パスプレフィックス(/api)を削除するよう指示します。
例:
https://example.com/api/usersmy-api へ /users として転送/api を削除された /users を処理これにより、アプリ側で/apiプレフィックスを考慮せずに実装できます。
機密性の高い管理画面には、Basic認証を追加して保護します。
# htpasswdコマンドでユーザ認証情報を生成
htpasswd -c /tmp/htpasswd admin
# パスワード入力プロンプトが出現
# New password: ****
# Re-type new password: ****
# ファイル内容を確認
cat /tmp/htpasswd
# 出力例:
# admin:$apr1$abcdef12$XXXXXXXXXXXXXXXXXXXXXXXXX
# Base64エンコード(Traefikが要求する形式)
htpasswd_content=$(cat /tmp/htpasswd | base64 -w0)
# Dokkuに設定
dokku config:set my-admin \
TRAEFIK_HTTP_MIDDLEWARES_ADMIN_AUTH_BASICAUTH_USERS="${htpasswd_content}" \
TRAEFIK_HTTP_ROUTERS_ADMIN_MIDDLEWARES=admin_auth@docker
# 認証なしでアクセス(401 Unauthorized が返される)
curl -I https://admin.example.com/
# 認証ありでアクセス
curl -I -u admin:password https://admin.example.com/
# 出力例:
# HTTP/2 200
Traefikはバックエンドのヘルスチェックをサポートしており、不健全なコンテナへのトラフィックを自動的に遮断できます。
まず、アプリ側で/healthzエンドポイントを実装します(例:Node.js)。
// app.js
app.get('/healthz', (req, res) => {
res.status(200).json({ status: 'ok' });
});
dokku config:set my-api \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_HEALTHCHECK_PATH='/healthz' \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_HEALTHCHECK_INTERVAL='10s' \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_HEALTHCHECK_TIMEOUT='5s'
# Traefikログでヘルスチェック結果を確認
dokku traefik:logs | grep healthz
# 出力例:
# time="2025-12-10T08:19:13Z" level=debug msg="Health check for my-api: ok"
Dokku + Traefik導入時に直面しやすい問題と、その解決方法を解説します。
原因候補:
対処方法:
# ラベル設定を確認
dokku config my-api | grep TRAEFIK
# アプリが起動しているか確認
dokku ps:list
# Traefikのルーター設定を確認
dokku traefik:logs | grep "my-api"
# DNS設定を確認
dig api.example.com
# Traefikコンテナに入ってデバッグ
docker exec -it traefik /bin/sh
# その中で curl http://my-api-web.dokku.svc.cluster.local:5000/ を試す
原因候補:
対処方法:
# ACME設定を確認
dokku config:get --global TRAEFIK_ACME_EMAIL
dokku config:get --global TRAEFIK_ACME_CA_SERVER
# Traefikログで証明書取得エラーを確認
dokku traefik:logs | grep -i "acme\|certificate"
# acme.jsonファイルが存在・読み取り可能か確認
ls -la /var/lib/traefik/acme.json
# ステージング環境でテスト中か確認
# (ステージング環境ではブラウザに警告が出ます)
原因候補:
TRAEFIK_HTTP_SERVICES_*_LOADBALANCER_SERVER_PORTが間違ったポート番号127.0.0.1だけをlistenしている(0.0.0.0にバインドする必要がある)対処方法:
# アプリのログを確認
dokku logs my-api
# コンテナに入ってポートをチェック
dokku enter my-api web
# コンテナ内でnetstatを実行
netstat -tlnp
# 出力例:
# Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program
# tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 1/node
# Dockerfileで EXPOSE を確認
cat Dockerfile | grep EXPOSE
原因候補:
対処方法:
# 全アプリのTraefik設定を一覧表示
for app in $(dokku apps:list); do
echo "=== $app ==="
dokku config $app | grep TRAEFIK
done
# Traefikダッシュボードで可視化(有効な場合)
# https://traefik.example.com/dashboard/
# ルール優先度を確認(Traefikログで)
dokku traefik:logs | grep -i "rule\|priority"
Dokku + Traefik環境を長期的に安定運用するための、実践的なベストプラクティスをまとめました。
ラベル名やルーター名を統一的なルールで命名することで、設定の可読性と管理性が大幅に向上します。
# 推奨パターン:
# TRAEFIK_HTTP_ROUTERS_<APPNAME>_*
# TRAEFIK_HTTP_SERVICES_<APPNAME>_*
# TRAEFIK_HTTP_MIDDLEWARES_<APPNAME>_<PURPOSE>_*
# 例:my-api アプリの場合
TRAEFIK_HTTP_ROUTERS_MYAPI_RULE='Host(`api.example.com`)'
TRAEFIK_HTTP_SERVICES_MYAPI_LOADBALANCER_SERVER_PORT=5000
TRAEFIK_HTTP_MIDDLEWARES_MYAPI_AUTH_BASICAUTH_USERS='...'
新しいアプリを追加・設定を変更する際の標準的なフロー:
staging-api.example.comなど)で動作確認README.mdなどにまとめておくAWS_ACCESS_KEY_IDやAWS_SECRET_ACCESS_KEYは絶対にGitにコミットしない。.envファイルで管理し、本番サーバにのみデプロイ# Traefikログを定期的に確認
dokku traefik:logs | tail -100
# エラーログだけをフィルタリング
dokku traefik:logs | grep -i "error\|warn"
# 本番環境では外部ログサービスに送信
# (Datadog, Splunk, CloudWatch など)
Let’s Encryptの証明書は90日有効で、30日前から自動更新が開始されます。
# 証明書の有効期限を確認
openssl s_client -connect api.example.com:443 -showcerts | \
openssl x509 -noout -dates
# 出力例:
# notBefore=Dec 10 08:19:13 2025 GMT
# notAfter=Mar 10 08:19:13 2026 GMT
同じ要件(複数サブドメイン、HTTPS、Basic認証)を実装する場合、設定量がどの程度削減されるか比較してみましょう。
# api.example.com 用の設定(HTTPSリダイレクト + TLS + Basic認証)
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /var/lib/dokku/letsencrypt/certs/api.example.com.crt;
ssl_certificate_key /var/lib/dokku/letsencrypt/certs/api.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
auth_basic "Restricted";
auth_basic_user_file /home/dokku/my-api/htpasswd;
proxy_pass http://my-api-80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /healthz {
proxy_pass http://my-api-80/healthz;
access_log off;
}
}
# admin.example.com 用の設定(同様に30〜40行)
# app.example.com 用の設定(同様に30〜40行)
# ... 合計120〜150行
総行数:約120〜150行
# api.example.com 用の設定
dokku config:set my-api \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_API_RULE='Host(`api.example.com`)' \
TRAEFIK_HTTP_ROUTERS_API_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_API_TLS=true \
TRAEFIK_HTTP_ROUTERS_API_TLS_CERTRESOLVER=letsencrypt \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_SERVER_PORT=5000 \
TRAEFIK_HTTP_MIDDLEWARES_API_AUTH_BASICAUTH_USERS='...' \
TRAEFIK_HTTP_ROUTERS_API_MIDDLEWARES=api_auth@docker \
TRAEFIK_HTTP_SERVICES_API_LOADBALANCER_HEALTHCHECK_PATH='/healthz'
# admin.example.com 用の設定(同様に8〜10行)
# app.example.com 用の設定(同様に8〜10行)
# ... 合計24〜30行
総行数:約24〜30行
さらに重要な点として、Traefik設定はプログラム的に扱える環境変数なため、設定の自動生成・バージョン管理・CI/CDパイプラインへの組み込みが容易です。
Traefik + Dokku環境で、自動HTTPS取得がどのように実現されるかを、詳しく解説します。
1. ユーザが https://api.example.com にアクセス
↓
2. Traefikが「api.example.com の証明書がない」と判定
↓
3. Traefikが Let's Encrypt に証明書リクエストを送信
↓
4. Let's Encrypt が DNS-01 チャレンジを要求
↓
5. Traefik が Route53 API を呼び出し
_acme-challenge.api.example.com の TXT レコードを作成
↓
6. Let's Encrypt が TXT レコードを確認(DNS反映待ち)
↓
7. 検証成功 → 証明書を発行
↓
8. Traefik が証明書を /var/lib/traefik/acme.json に保存
↓
9. Traefik が新しい証明書をロード
↓
10. ユーザが https://api.example.com にアクセス可能に
Let’s Encryptの証明書は90日間有効です。Traefikは自動的に以下のスケジュールで更新を試みます。
# 証明書ファイルから有効期限を確認
openssl x509 -in /var/lib/traefik/acme.json -noout -dates
# または、ブラウザのアドレスバーの鍵アイコンから確認
# → 「証明書を表示」→「有効期間」を確認
DNS-01検証(Route53を使用)には、HTTP-01検証にない利点があります。
| 項目 | HTTP-01 | DNS-01 |
|---|---|---|
| ポート | 80番が必要 | ポート不要 |
| ファイアウォール | ポート80を開放必須 | 制限可能 |
| ワイルドカード証明書 | 不可 | 可能 |
| 複数IPでの運用 | 各IPで検証が必要 | 1つのDNS設定で完結 |
| CDN背後での運用 | 複雑 | シンプル |
実際の運用では、様々なシナリオに直面します。以下は代表的なケースと対応方法です。
既存のv1から新しいv2へ、トラフィックを段階的に移行したい場合:
# v1 アプリ(既存)
dokku apps:create my-api-v1
dokku config:set my-api-v1 \
TRAEFIK_HTTP_ROUTERS_API_RULE='Host(`api.example.com`)' \
TRAEFIK_HTTP_ROUTERS_API_ENTRYPOINTS=web,websecure \
TRAEFIK_HTTP_ROUTERS_API_TLS=true
# v2 アプリ(新規)
dokku apps:create my-api-v2
dokku config:set my-api-v2 \
TRAEFIK_ENABLE=false # 最初は無効化
# v2 のテスト完了後、ラベルを有効化
dokku config:set my-api-v2 \
TRAEFIK_ENABLE=true \
TRAEFIK_HTTP_ROUTERS_APIV2_RULE='Host(`api-v2.example.com`)' \
...
# トラフィック切り替え:v1 を無効化、v2 を有効化
dokku config:set my-api-v1 TRAEFIK_ENABLE=false
dokku config:set my-api-v2 TRAEFIK_ENABLE=true
# (ラベルを付け替える)
トラフィック急増に対応するため、同じアプリを複数インスタンス起動したい場合:
# 既存アプリのスケール設定
dokku ps:scale my-api=3 # 3個のプロセスを起動
# Traefik は自動的に複数インスタンスにロードバランシング
# (ラベル設定は変更不要)
同じコードベースをステージング・本番で並行運用する場合:
# ステージング環境
dokku apps:create my-api-staging
dokku config:set my-api-staging \
TRAEFIK_HTTP_ROUTERS_API_STAGING_RULE='Host(`staging-api.example.com`)' \
...
# 本番環境
dokku apps:create my-api-production
dokku config:set my-api-production \
TRAEFIK_HTTP_ROUTERS_API_PROD_RULE='Host(`api.example.com`)' \
...
# 本番環境でのテスト完了後、本番環境にデプロイ
Dokku + Traefikの組み合わせにより、以下のような理想的なデプロイ環境が実現されます。
✅ nginxの複雑な設定ファイルから解放
アプリにラベルを付けるだけでルーティング完成。ファイル編集による誤設定のリスク排除。
✅ 自動HTTPS取得・更新
Let’s Encryptとの連携で、証明書の取得・更新が完全自動化。有効期限切れの心配なし。
✅ スケーラビリティ
新しいサブドメインやサービスを追加する際、設定行数はほぼ一定。サービス数が増えても管理負荷が増えない。
✅ 可視化とデバッグ
Traefikダッシュボードでルーティング状態をリアルタイムに確認。問題発生時の原因特定が容易。
✅ セキュリティ強化
Basic認証、IP制限、ヘッダ操作などをミドルウェアで一元管理。設定の統一性が向上。
✅ 運用効率化
CI/CDパイプラインに設定を組み込み、デプロイ時の設定変更を自動化可能。
本記事で紹介した基本的な設定ができたら、以下の発展的なトピックにも挑戦してみてください。
*.example.comで複数サブドメインをカバーDokku + Traefikは、小規模スタートアップから中堅企業まで、あらゆる規模のセルフホスト環境に対応できる、実用的で拡張性の高いソリューションです。
本記事で紹介した内容は、2025年12月時点のバージョンに基づいています。ツールのアップデートに伴い、コマンドやパラメータが変更される可能性があるため、最新のドキュメントを合わせて参照することをお勧めします。
記事数の多いカテゴリから探す