Cloudflare Tunnelで自宅NASを外から使う!Docker Compose構成を図解

自宅NASのImmichやHome Assistantへ、外出先から安全にアクセスしたい!
でも、ルーターのポート開放やDockerのネットワークがよく分からない……。

Cloudflare Tunnelを使えば、NASからCloudflareへ外向きの接続を作れます。
この記事では、完成した構成と設定手順を図中心で整理します。
結論
情報
- ルーターの受信ポートを開けずに、NAS上のWebアプリを公開できる
- Immichの接続先は
http://immich-server:2283 network_mode: hostのHome Assistantはhttp://<NASのLAN IP>:8123- Home Assistantには
trusted_proxiesの設定も必要
迷いやすいのは、ImmichとHome AssistantでService URLの書き方が違う点です。結論だけ覚えるなら、bridge内のサービスはDockerのサービス名、host networkのサービスはNASのLAN IPを使います。
今回の構成
通信は次の順番です。
- スマホやPCが公開URLへHTTPSでアクセスする
- Cloudflareが公開ホスト名を判定する
- 確立済みのTunnelを通してNAS上のcloudflaredへ届ける
- cloudflaredがImmichまたはHome Assistantへ振り分ける
NAS側からCloudflareへ接続を開始するため、ルーターでインターネット向けの受信ポートを開ける必要はありません。
Cloudflare側でTunnelを作る
Cloudflareダッシュボードで次の順番に設定します。
- Networking → Tunnelsを開く
- Create Tunnelを選ぶ
- Tunnel名を入力する
- Setup EnvironmentでDockerを選ぶ
- 表示されたコマンドからTunnelトークンをコピーする
公式手順はこちらです。
cloudflaredをDocker Composeへ追加する
docker-compose.ymlへ次のサービスを追加します。
12345678services:
cloudflared:
container_name: cloudflared
image: cloudflare/cloudflared:latest
command: tunnel --no-autoupdate run
environment:
TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN:?Set CLOUDFLARE_TUNNEL_TOKEN in .env}
restart: unless-stopped.envへTunnelトークンを保存します。
1CLOUDFLARE_TUNNEL_TOKEN=<CloudflareでコピーしたTunnelトークン>起動と確認は次の3コマンドです。
123docker compose config --quiet
docker compose up -d cloudflared
docker compose logs --tail=200 cloudflaredcloudflaredがUpになり、ログに接続成功が出れば、NASとCloudflareのTunnelは完成です。
bridgeとhost networkの違い
通常のComposeサービスは、Composeが作るbridgeネットワークへ入ります。同じbridge内ではDockerのDNSが使えるため、cloudflaredからImmichへサービス名で接続できます。
1http://immich-server:2283一方、Home Assistantは次の設定です。
12homeassistant:
network_mode: hosthostは、Home AssistantがNAS本体と同じネットワーク環境を共有する設定です。Composeのbridgeには参加しないため、homeassistant:8123ではなくNASのLAN IPへ接続します。
1http://<NASのLAN IP>:8123同じComposeファイルに書かれていても、必ず同じDockerネットワークにいるとは限らない、という点がポイントです。
公開ルートを設定する
作成したTunnelのRoutes → Add route → Published applicationから、公開ホスト名とService URLを登録します。
| 公開対象 | 公開ホスト名の例 | Service URL |
|---|---|---|
| Immich | immich.example.com | http://immich-server:2283 |
| Home Assistant | home.example.com | http://<NASのLAN IP>:8123 |
ここでcloudflaredが、公開ホスト名に応じてNAS内の接続先を選びます。公開側のHTTPSを受けて内部のHTTPサービスへ転送するため、リバースプロキシとして動いています。
Home Assistantをサービス名にすると502になる
network_mode: hostのHome Assistantはbridge内にいません。http://homeassistant:8123ではなく、NAS本体のLAN IPを指定します。
Home Assistantのプロキシ設定
Cloudflare経由では、Home Assistantへ最後に接続するのはcloudflaredです。そのため、Home Assistantへ信頼するプロキシを設定します。
まずComposeのdefaultネットワークを確認します。
123docker network ls
docker network inspect <Composeのdefaultネットワーク名> \
--format '{{(index .IPAM.Config 0).Subnet}}'確認したサブネットをhomeassistant-config/configuration.yamlへ設定します。
1234http:
use_x_forwarded_for: true
trusted_proxies:
- <docker network inspectで確認したサブネット>設定後にHome Assistantを再起動します。
12docker compose restart homeassistant
docker compose logs --tail=200 homeassistantHome Assistant公式の説明はこちらです。
つながらないときの確認
症状ごとに確認する場所を分けます。
| 症状 | 確認する場所 |
|---|---|
| TunnelがHealthyにならない | Tunnelトークン、NASの外向き通信、cloudflaredのログ |
| 502 Bad Gateway | Cloudflare側のService URL、対象コンテナの起動状態 |
| Home Assistantだけ400またはproxy警告になる | use_x_forwarded_forとtrusted_proxies |
1234docker compose ps
docker compose logs --tail=200 cloudflared
docker compose logs --tail=200 immich-server
docker compose logs --tail=200 homeassistant補足しておきたい注意点
- Published applicationへ登録するのはImmich ServerやHome Assistantだけ。PostgresやValkeyは公開しない
- Tunnelは通信経路を作る仕組み。アプリ自身の認証や多要素認証は別途設定する
- Tunnelトークンとパスワードは
.envなどへ分離し、Gitへコミットしない - 大きな動画はCloudflare側のアップロード上限に当たる場合があるため、実ファイルで確認する
- 外からアクセスできることとバックアップは別。写真、DB、Home Assistant設定は別途バックアップする
まとめ
- Cloudflare Tunnelなら、ルーターの受信ポートを開けずにNAS上のWebアプリを公開できる
cloudflaredは既存のDocker Composeへ追加し、トークンは.envから渡す- Immichは
http://immich-server:2283 - host networkのHome Assistantは
http://<NASのLAN IP>:8123 - Home Assistantでは
trusted_proxiesも設定する
構成を理解するコツは、cloudflaredから見て接続先がbridge内なのか、NAS本体のhost networkなのかを分けて考えることです。
Thanks for reading!
最後まで読んでくれてありがとう🔥

