はじめに
自宅サーバーを外部公開したいけれど、次のような壁にぶつかることが多いです。
- 固定 IP がない
- 回線が CGNAT でポート開放できない
- ルーター設定を増やしたくない
この問題をシンプルに解決できるのが Cloudflare Tunnel です。サーバー側から Cloudflare に向けてアウトバウンド接続を張るため、基本的に固定 IP やポート開放が不要です。
この記事では、Docker で cloudflared を動かし、https://app.example.com のようなホスト名で自宅サービスを公開する手順をまとめます。
Cloudflare Tunnel の構成
今回の構成は次の通りです。
[Browser]
|
| HTTPS
v
[Cloudflare Edge]
|
| Tunnel (Outbound from home)
v
[cloudflared container] ---> [local service container (nginx/immich/etc)]
ポイントは、外部から自宅へ直接入ってくる接続ではなく、cloudflared が作るトンネル経由になることです。
前提条件
- Cloudflare アカウント
- Cloudflare で管理しているドメイン(例:
example.com) - Docker / Docker Compose が使える Linux サーバー
手順 1: Cloudflare 側でトンネルを作成
- Cloudflare ダッシュボードで
Zero Trustを開く Networks->TunnelsでCreate a tunnelCloudflaredを選び、トンネル名を作成- 表示される トークン を控える
このトークンを使えば、サーバー側はログイン不要でトンネルを起動できます。
手順 2: Docker Compose で cloudflared を起動
以下は最小構成の例です。nginx を公開対象にしています。
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
command: tunnel --no-autoupdate run --token ${CF_TUNNEL_TOKEN}
restart: unless-stopped
depends_on:
- app
app:
image: nginx:alpine
container_name: app
restart: unless-stopped
.env にトークンを保存します。
CF_TUNNEL_TOKEN=xxxxxxxxxxxxxxxx
起動:
docker compose up -d
手順 3: 公開ホスト名を設定
Cloudflare 側のトンネル設定で Public Hostname を追加します。
- Subdomain:
app - Domain:
example.com - Service Type:
HTTP - URL:
app:80
これで https://app.example.com からコンテナ app に到達できます。
最低限のセキュリティ設定
公開直後に、次の 3 点は設定しておくのがおすすめです。
Zero TrustのAccessでメール認証や IdP ログインを要求する- Cloudflare 側で WAF / Bot 対策を有効化する
cloudflaredと公開アプリのコンテナを定期更新する
トラブルシュート
502が出る:Public Hostnameの URL(app:80など)が誤っていることが多いcloudflaredが再起動を繰り返す: トークンのコピーミス、期限切れを確認- ドメインで開けない: Cloudflare 側で対象ドメインが正しく有効化されているか確認
まとめ
Cloudflare Tunnel を使えば、固定 IP なし・ポート開放なしでも自宅サービスを公開できます。特に CGNAT 環境では効果が大きく、公開の難易度を一気に下げられます。
まずは 1 サービスだけトンネル化して動作確認し、問題なければ Immich や管理画面系サービスへ段階的に広げる運用がおすすめです。