Cloudflare Tunnelで自宅サーバーを公開する【Cloudflare運用記録 #3】
はじめに
こんにちは。
なかのひとカンパニーの archer です。
前回は、Cloudflare Workers・D1・R2などの無料枠についてまとめました。
今回は少し構成を変えて、自宅サーバーの話です。
私は自宅にProxmoxを置いていて、その中にUbuntuのVMを作り、DockerでWebサービスを動かしています。
構成としては、だいたいこんな形です。
インターネット
↓
Cloudflare
↓
Cloudflare Tunnel
↓
cloudflared
↓
Nginx
↓
Docker
↓
Webアプリ
最初は、
「自宅サーバーを外部公開するなら、ルーターでポートを開ければいいのでは」
とも考えました。
ただ、実際にサービスを公開するなら、
- グローバルIP
- ポート開放
- HTTPS
- 証明書
- DNS
- セキュリティ
なども考える必要があります。
そこで使ったのがCloudflare Tunnelでした。
自宅サーバーをそのまま公開したくなかった
自宅サーバーでWebサービスを公開する方法はいくつかあります。
単純に考えるなら、
インターネット
↓
自宅ルーター
↓
ポートフォワーディング
↓
サーバー
という構成です。
ただ、この方法では外部から自宅側へ直接通信を受けることになります。
個人的には、
Webサービスを公開するために、自宅ネットワーク側でインバウンドの穴を増やしたくない
という気持ちがありました。
そこでCloudflare Tunnelを使いました。
Cloudflare Tunnelでは、自宅サーバー側で動く cloudflared がCloudflareへ接続します。
通信の開始方向は、
自宅サーバー
↓
Cloudflare
です。
外部から自宅サーバーへ直接接続を開始する形ではありません。
そのため、Webサービスを公開するためだけにルーターで80番や443番ポートを開放する必要がなくなります。
Cloudflare Tunnelの仕組み
Cloudflare Tunnelでは、サーバー側に cloudflared というソフトウェアを動かします。
ざっくり言えば、
利用者
↓
Cloudflare
↓
Tunnel
↓
cloudflared
↓
自宅のWebサービス
という流れです。
たとえば、
https://example.com
へのアクセスを、
http://localhost:8080
へ転送できます。
Cloudflare側では、
app.example.com
↓
http://localhost:8080
のように、
公開するホスト名と、自宅側のサービス
を紐づけます。
自宅側のWebサーバーがインターネットから直接見えているわけではありません。
自分の構成
自分の場合は、自宅サーバーにProxmoxを入れています。
その上にUbuntu VMを作っています。
Ubuntu上ではDockerを使ってWebサービスを動かしています。
構成はこんな感じです。
Proxmox
└─ Ubuntu VM
├─ Docker
│ └─ Webアプリ
│
├─ Nginx
│
└─ cloudflared
外部から見ると、
Browser
↓
Cloudflare
↓
Cloudflare Tunnel
↓
cloudflared
↓
Nginx
↓
Docker
↓
Webアプリ
という流れになります。
なぜNginxを挟んでいるのか
Cloudflare Tunnelから直接DockerのWebアプリへ接続することもできます。
たとえば、
Cloudflare Tunnel
↓
localhost:3000
↓
Next.js
でも動かせます。
それでも自分はNginxを挟んでいます。
理由は、
Cloudflareとアプリの間に、自分で管理できる入口を1つ置いておきたかったから
です。
たとえば、
Cloudflare Tunnel
↓
Nginx
├─ / → Webアプリ
├─ /api → API
└─ /other → 別サービス
のようにできます。
アプリが増えても、Nginx側で整理できます。
Cloudflare Tunnelは、
「自宅ネットワークまで通信を持ってくるもの」
Nginxは、
「自宅ネットワークに入ってきたHTTP通信を振り分けるもの」
という役割に分けています。
Tunnelを作る
Cloudflareの管理画面からTunnelを作成できます。
現在のCloudflareでは、
Networking
↓
Tunnels
↓
Create Tunnel
という流れで作成できます。
Tunnelを作ると、サーバーへ cloudflared をインストールして接続するためのコマンドが表示されます。
Ubuntuなどで cloudflared を動かすと、自宅サーバーからCloudflareへのTunnelが確立されます。
重要なのは、
自宅側からCloudflareへ接続している
という点です。
従来の、
外部
↓
自宅ルーター
↓
自宅サーバー
ではなく、
自宅サーバー
↓
Cloudflare
という接続を先に作っています。
そのTunnelを経由して、利用者からの通信が自宅側へ届きます。
Public Hostnameを設定する
次に、
app.example.com
のような公開URLと、自宅側のサービスを紐づけます。
たとえばNginxを80番ポートで動かしているなら、
Public hostname
app.example.com
Service
http://localhost:80
のような設定になります。
すると、
https://app.example.com
へアクセスした通信が、
Cloudflare
↓
Tunnel
↓
cloudflared
↓
localhost:80
へ届きます。
その先はNginxがDockerのWebアプリへ転送します。
HTTPSを自宅側で考えなくてよくなった
これもCloudflareを使って楽になった部分です。
通常、自宅サーバーをHTTPSで公開しようとすると、
ドメイン
証明書
証明書更新
Webサーバー
などを考える必要があります。
もちろんLet's Encryptなどを使えば実現できます。
ただ、証明書の更新なども自分で管理する要素になります。
Cloudflareを入口にすると、利用者とCloudflare間のHTTPSをCloudflare側で扱えます。
自宅側では、
Cloudflare Tunnel
↓
http://localhost
という構成も取れます。
自宅サーバーで公開用の証明書を直接管理する必要が減りました。
個人開発では、こういう小さな管理項目が減るだけでもかなり楽です。
公開IPを意識しなくていい
Cloudflare Tunnelを使って便利だったもう一つの点が、
公開用のグローバルIPを意識しなくていいこと
です。
自宅回線では、
- IPアドレスが変わる
- 固定IPではない
- そもそも外部から直接接続しにくい
といったことがあります。
Cloudflare Tunnelの場合、cloudflared からCloudflareへ接続するため、
このIPアドレスへアクセスしてください
という構成ではありません。
ドメイン側はCloudflareへ向けておき、
その先をTunnelが自宅サーバーへつなぎます。
自宅回線でサービスを公開するときには、かなり扱いやすい仕組みだと感じました。
もちろん自宅サーバー側が落ちれば止まる
Cloudflare Tunnelを使ったからといって、自宅サーバーがクラウドになるわけではありません。
当然、
停電
Ubuntu停止
Proxmox停止
Docker停止
Nginx停止
cloudflared停止
自宅回線停止
のどれかが起きればサービスは止まります。
Cloudflareまでは正常でも、
Cloudflare
↓
Tunnel
↓
自宅サーバー ×
ならサービスは利用できません。
Cloudflare Tunnelは、
自宅サーバーを高可用なサーバーにしてくれるものではない
という点は重要です。
あくまで、自宅のサービスをCloudflare経由で公開する仕組みです。
cloudflared自体の冗長化もできる
Cloudflare Tunnelでは、同じTunnelに複数の cloudflared を接続できます。
そのため、
Cloudflare
├─ cloudflared A
└─ cloudflared B
のような構成も可能です。
Cloudflareの公式ドキュメントでは、1つの cloudflared は複数のCloudflareデータセンターへ複数の接続を張ります。
さらに必要なら、同じTunnelへ別の cloudflared をReplicaとして追加できます。
ただ、自分の個人開発では、
自宅サーバー自体が1台
なので、そこまで冗長化しても意味が薄いケースもあります。
このあたりは、
どこまで止めたくないサービスなのか
によって考えればいいと思っています。
セキュリティ的にも分かりやすくなった
自宅サーバーを直接公開する場合、
ルーター
↓
ポート開放
↓
Nginx
↓
アプリ
という入口があります。
Cloudflare Tunnelでは、Webサービス公開のためのインバウンドポートを開けずに構成できます。
もちろん、
Tunnelを使えば自動的に安全になる
という意味ではありません。
アプリに脆弱性があれば攻撃される可能性はあります。
認証が必要なサービスなら、認証も必要です。
OSやDockerの更新も必要です。
ただ、
「自宅サーバーへどうやって外部通信を到達させるか」
という部分は、かなりシンプルになりました。
自宅サーバーとCloudflareは意外と相性がいい
最初は、
自宅サーバー
vs
Cloudflare
のように考えていました。
クラウドを使うのか。
自宅サーバーを使うのか。
どちらかを選ぶものだと思っていました。
実際には、
Cloudflare
+
自宅サーバー
という組み合わせもかなり便利でした。
計算資源やDockerは自宅に置く。
公開部分はCloudflareに任せる。
この分担です。
自宅サーバーの自由さを残しつつ、
外部公開の面倒な部分をCloudflareに任せられます。
今回使ったサービスの料金
Cloudflare Tunnelは、公開Webアプリケーション用途ではCloudflareの各プランで利用できます。
Tunnelを使うためだけに、自宅側へ固定IPを契約したり、別の公開用サーバーを用意したりする必要はありません。
ただし、
自宅サーバーだから0円
ではありません。
自宅側では、
- サーバー本体
- ストレージ
- 電気代
- インターネット回線
- 故障時の交換
などのコストがあります。
クラウドの請求書には出ませんが、実際にはコストです。
自宅サーバーの場合、
Cloudflare利用料
+
ハードウェア代
+
電気代
+
自分で運用する時間
まで含めて考えた方がいいと思います。
自分の場合、すでにProxmoxサーバーを持っているため、
既存の自宅サーバーを外部公開する追加コストをかなり抑えられる
というのがCloudflare Tunnelのメリットでした。
※料金や利用条件は2026年8月時点の情報を前提としています。
最新の料金・制限についてはCloudflare公式ドキュメントを確認してください。
まとめ
今回はCloudflare Tunnelを使って、自宅サーバー上のWebサービスを公開する構成についてまとめました。
自分の構成は、
Browser
↓
Cloudflare
↓
Cloudflare Tunnel
↓
cloudflared
↓
Nginx
↓
Docker
↓
Webアプリ
です。
Cloudflare Tunnelを使って良かったのは、
- Web公開のために自宅側の受信ポートを開けなくていい
- 公開IPをあまり意識しなくていい
- HTTPS周りをCloudflareへ寄せられる
- 自宅サーバーの自由度を残せる
- NginxやDockerの既存構成をそのまま使える
というところでした。
Cloudflareを使い始めてから、
「クラウドか自宅サーバーか」
という二択ではなく、
自宅サーバーの面倒な部分だけCloudflareに任せる
という選択肢もあるのだと感じています。
次回は、自宅サーバーから離れて、
Cloudflare WorkersでNext.jsを動かす
構成について書きます。
サーバーやDockerそのものを管理せずに、Next.jsをCloudflareへデプロイするとどう変わるのかをまとめる予定です。
