Contents
前提条件と全体像
本ガイドでは、Docker 上に Traefik v3 をデプロイし、Cloudflare の API トークン を利用して Let’s Encrypt からワイルドカード証明書(*.example.com)を自動取得・更新する手順を解説します。
この構成は以下の点で重要です。
- HTTPS 化が必須なマルチテナント環境でも、ポート 80 が閉じていても証明書取得できる。
- 最小権限の API トークンを使うことで、トークン漏洩時のリスクを低減できる。
以下では、必要な前提条件からインストール、設定ファイル作成、動作確認、運用・トラブルシューティングまでを段階的に示します。
必要なソフトウェアとバージョン(2026年6月現在)
| ソフトウェア | 推奨バージョン | 入手先 |
|---|---|---|
| Docker Engine | ≥ 23.0 (Ubuntu 22.04 LTS の公式パッケージ) | https://docs.docker.com/engine/install/ |
| Docker Compose | v2.27.0 以上 | https://github.com/docker/compose/releases |
| Traefik | v3.0 (最新安定版) | https://doc.traefik.io/traefik/ |
| Cloudflare API | Edit zone DNS 権限を持つトークン | Cloudflare ダッシュボード |
Docker と Docker Compose のインストール
Docker と Docker Compose が未インストールの場合は、以下の手順でセットアップします。各コマンドは Ubuntu 22.04 LTS を想定していますが、他ディストリビューションでも同様の流れです。
Docker Engine のインストール
Docker の公式リポジトリを追加し、最新版をインストールします。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release # GPG 鍵の取得と保存 curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # apt ソースリストに追加 echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # インストール sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io |
インストール後にバージョンを確認し、23.0 以上であることを確かめます。
|
1 2 3 |
docker version --format '{{.Server.Version}}' # => 23.x.x (例) |
Docker Compose のインストール
公式バイナリをダウンロードして実行権限を付与します。
|
1 2 3 4 5 6 7 |
sudo curl -L "https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-$(uname -s)-$(uname -m)" \ -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # バージョン確認 docker compose version # => Docker Compose v2.27.0 |
ポイント:Docker と Compose のバージョンが公式推奨を上回っていれば、Traefik は問題なく動作します。
Cloudflare API トークンの取得と安全な取り扱い
Cloudflare で DNS‑01 チャレンジを利用するには、最小権限(Edit zone DNS)の API トークンが必要です。このトークンは環境変数 CF_API_TOKEN 経由でコンテナに渡すことで、平文で設定ファイルに記載しないようにします。
手順概要
- Cloudflare にログイン → 左メニューの My Profile > API Tokens を開く。
- Create Token ボタンをクリックし、テンプレートから “Edit zone DNS” を選択。
- 対象ゾーン(例:
example.com)のみをスコープに指定し、トークン名を入力して作成。
環境変数としての注入方法
- トークンはプロジェクトルートに
.envファイルを作成し、Git 管理から除外(.gitignoreに*.envを追加)します。
|
1 2 3 |
# .env (例) CF_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxx |
Docker Compose は自動的に .env を読み込み、environment: セクションで変数展開できます。
出典:Cloudflare の公式ドキュメント「API Tokens」を参照。
Traefik 基本設定ファイルの作成
Traefik の設定は YAML(traefik.yml)または TOML 形式で記述できますが、ここでは YAML を採用します。以下の構成は最小限かつベストプラクティスを盛り込んだものです。
traefik.yml の全体像
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# traefik.yml log: level: DEBUG # デバッグログで ACME 流れを可視化 entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" providers: docker: exposedByDefault: false # 明示的にラベル付与したコンテナだけ公開 certificatesResolvers: letsencrypt: acme: email: your@email.com storage: /letsencrypt/acme.json dnsChallenge: provider: cloudflare delayBeforeCheck: 0 # TTL が短い環境向けに即時検証 api: dashboard: true insecure: false # ダッシュボードは認証で保護 entryPoints: traefik: address: ":8080" |
各項目の簡易解説
log.level:DEBUG にすると ACME の取得・更新過程が詳細に出力され、トラブル時に有用。redirections:HTTP → HTTPS の自動リダイレクトを設定し、全通信を暗号化。providers.docker.exposedByDefault: false:意図しないコンテナが外部公開されるのを防止。certificatesResolvers.letsencrypt.acme.storage:証明書情報は永続ボリュームに保存し、再起動後も保持。dnsChallenge.provider: cloudflare:Cloudflare API を利用した DNS‑01 チャレンジ。api.insecure: falseと Basic Auth(後述)でダッシュボードへの不正アクセスを防止。
Docker Compose によるデプロイ
Docker Compose では Traefik コンテナと永続化用ボリュームだけを定義すれば、ワンコマンドで起動できます。以下は 最小構成 として推奨する docker-compose.yml の例です。
docker-compose.yml 全体
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
version: "3.8" services: traefik: image: traefik:v3.0 command: - --configFile=/etc/traefik/traefik.yml ports: - "80:80" - "443:443" - "8080:8080" # ダッシュボード用 (Basic Auth で保護) volumes: - "./traefik.yml:/etc/traefik/traefik.yml:ro" - "letsencrypt:/letsencrypt" - "/var/run/docker.sock:/var/run/docker.sock:ro" environment: - CF_API_TOKEN=${CF_API_TOKEN} restart: unless-stopped volumes: letsencrypt: |
設定ポイント
portsに 8080 を追加し、ダッシュボードへのアクセス用エントリーポイントを公開。environmentで.envのCF_API_TOKENが自動的に注入されます。- 永続化ボリューム
letsencryptはacme.jsonを格納し、証明書の永続化を実現。
acme.json の作成と権限設定
|
1 2 3 4 |
mkdir -p ./letsencrypt touch ./letsencrypt/acme.json chmod 600 ./letsencrypt/acme.json # 読み取りはコンテナ内部だけに限定 |
注意:パーミッションが緩すぎると Traefik 起動時に
permission deniedエラーが出ます。
Traefik ダッシュボードの認証保護(Basic Auth)
ダッシュボードは管理情報が露出するため、必ず Basic Auth で保護します。以下では htpasswd コマンドでハッシュ化したパスワードを利用する手順を示します。
1. 認証情報の生成
|
1 2 3 4 |
# htpasswd がインストールされていない場合: sudo apt-get install apache2-utils htpasswd -nb admin StrongPassword123 # => admin:$apr1$H6z8JkXb$5yM0eV3gT2E9vZQhK4YjF/ |
生成された文字列(admin:$apr1$...)をコピーします。
2. 動的設定ファイル middlewares.yml の作成
|
1 2 3 4 5 6 7 8 |
# middlewares.yml (traefik 用動的設定) http: middlewares: dashboard-auth: basicAuth: users: - "admin:$apr1$H6z8JkXb$5yM0eV3gT2E9vZQhK4YjF/" |
3. traefik.yml に動的設定ファイルを読み込む指示を追加
|
1 2 3 4 5 6 7 8 9 |
providers: file: directory: /etc/traefik/dynamic # コンテナ内のパス # 既存の api 設定に続けて api: dashboard: true insecure: false |
4. Docker Compose にボリュームマウントを追加
|
1 2 3 4 |
volumes: - "./traefik.yml:/etc/traefik/traefik.yml:ro" - "./middlewares.yml:/etc/traefik/dynamic/middlewares.yml:ro" |
5. ダッシュボードへのアクセス確認
ブラウザで http://<サーバIP>:8080/dashboard/ にアクセスすると、ユーザー名とパスワードの入力が求められます。正しく認証できればダッシュボードが表示されます。
ベストプラクティス:管理者アカウントは定期的にローテーションし、強力なパスフレーズを使用してください。
Cloudflare DNS‑01 チャレンジでワイルドカード証明書取得
手順概要
- Traefik 起動 → ACME クライアントが
CF_API_TOKENを用いて_acme-challenge.example.comの TXT レコードを作成。 - Let’s Encrypt が DNS レコードの存在確認後、ワイルドカード証明書(
*.example.com)とベースドメイン証明書を発行。 - 証明書は
acme.jsonに永続保存され、期限が近づくと自動的に更新処理が走る。
DNS‑01 のオプション詳細
| オプション | 説明 |
|---|---|
provider: cloudflare |
Cloudflare API を利用することを指定。 |
delayBeforeCheck |
DNS 変更直後の検証待機秒数(TTL が短い環境では 0、長めにしたい場合は 10 等)。 |
外部情報の要約:2025 年に公開された Mayopan 記事「Traefik v3 を Docker で構築し Let’s Encrypt のワイルドカード証明書を取得してみた」では、同様の手順と
delayBeforeCheck: 0が推奨されていることが報告されています(Mayopan, 2025)。本ガイドはその内容を踏まえて最新の公式情報に合わせています。
動作確認手順
基本的な HTTP/HTTPS テスト
|
1 2 3 4 5 6 7 8 |
# 1. HTTP → HTTPS のリダイレクト確認 curl -I http://example.com | grep -i location # => Location: https://example.com/ # 2. TLS 接続とステータスコード確認 curl -I https://example.com | head -n 3 # => HTTP/2 200 |
証明書情報の取得
|
1 2 3 |
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -dates -subject -issuer |
出力例:
|
1 2 3 4 5 |
notBefore=Jun 12 00:00:00 2026 GMT notAfter=Sep 11 23:59:59 2026 GMT subject=CN=*.example.com issuer=C = US, O = Let's Encrypt, CN = R3 |
ダッシュボードへの認証テスト
ブラウザで http://<IP>:8080/dashboard/ にアクセスし、先ほど設定した admin / StrongPassword123 でログインできることを確認します。
トラブルシューティングとベストプラクティス
よくあるエラーと対処法(まとめ)
| エラーメッセージ | 主な原因 | 推奨解決策 |
|---|---|---|
port 80 is already in use |
ホスト上の別サービスが 80 番ポートを占有 | sudo lsof -i :80 でプロセス特定し、停止または Traefik のポート変更 |
DNS timeout |
Cloudflare API が遅延/TTL が長い | delayBeforeCheck に数秒の余裕 (10) を設定 |
CF_API_TOKEN permission denied |
トークンに必要権限が付与されていない | ダッシュボード → API Tokens で「Edit zone DNS」スコープを再確認 |
acme.json: permission denied |
ファイル所有者・パーミッション不正 | chmod 600 acme.json && chown $(whoami):$(whoami) acme.json |
セキュリティ上の追加対策
- 最小権限トークンを必ず使用し、不要なスコープは外す。
acme.jsonは 600 権限で保護し、ホスト側でもマウント先ディレクトリへのアクセス制御を行う。- ダッシュボードは Basic Auth + HTTPS で保護し、IP 制限(Traefik の
middlewares.ipWhiteList)を併用するとさらに安全です。
IP ホワイトリスト例(H4)
|
1 2 3 4 5 6 7 |
http: middlewares: admin-ip-whitelist: ipWhiteList: sourceRange: - "203.0.113.0/24" # 管理者が利用する社内ネットワーク |
このミドルウェアをダッシュボードのエントリポイントに適用すれば、許可された IP からのみアクセス可能になります。
まとめ
- Docker + Traefik v3 の構成で、Cloudflare DNS‑01 によりワイルドカード証明書を自動取得・更新できる。
- 最小権限の API トークンと 環境変数
.envで安全にトークンを管理し、平文保存は避ける。 - ダッシュボードは Basic Auth + IP ホワイトリスト によって保護し、外部からの不正閲覧を防止する。
- 設定変更やアップデート時は公式ドキュメントと本ガイドの日付(2026年6月)を基準に確認し、バージョン差異による問題を未然に防ぐ。
この手順通りに実装すれば、Docker 環境で安全かつスケーラブルな HTTPS インフラが構築できます。質問やトラブルが生じた場合は、本稿の「トラブルシューティング」セクションと公式リポジトリの Issue トラッカーを併せてご活用ください。