
- はじめに
- コストについて
- 従来の自宅サーバ公開で詰まりやすいところ
- Cloudflare Tunnelは何をしているのか
- Cloudflareはどこで登場するのか
- 今回作る構成
- 手順1: Cloudflareにドメインを追加する
- 手順2: Zero TrustでTunnelを作る
- 手順3: 自宅サーバでcloudflaredを動かす
- 手順4: 公開アプリケーションルートを作る
- 手順5: 動作確認する
- まとめ
- 参考にした公式ドキュメント
はじめに
こんにちは! 株式会社アドグローブ ゲーム事業本部 エンジニアの九津見です。
ウェブサービスを公開しようとする場合、クラウドサービスを利用する場合が多いと思いますが、昨今では円安の影響もあり、前ほど気軽に立てるということが難しくなってきていると感じています。
比較的シンプルなデータの出し入れをするAPIの構築であれば、PaaSに頼ることで限りなくコストを抑えるという選択肢もありますが、少しCPUを使う、メモリを食う、ストレージを多めに持つ、GPUを触りたい、という用途では厳しいという現実があります。
私自身、自前のサービスをいくつか公開しているのですが、動作できるぎりぎりの性能で攻めても毎月の運用費が無視できない金額になってきたため、重い腰を上げて根本的なコスト削減に取り組むことにしました。
性能もほしい、ランニングコストも下げたい、となった結果たどり着いたのは『Cloudflare Tunnel+自宅サーバ』の構成でした。
この記事では、Cloudflare(https://www.cloudflare.com/ja-jp/)のサービス『Cloudflare Tunnel』を使って、自宅サーバ上のサービスを独自ドメインで公開する流れをまとめます。単に手順だけではなく、Cloudflareがどこで何をしているのか、なぜ固定IPやポート開放なしで公開できるのかを見ていきます。
コストについて
Cloudflare Tunnel+自宅サーバの構成でかかるコストは以下の通りです。
- サーバ購入費(新しくハードウェアを購入するなら)
- サーバを動かす電気代
- インターネット回線費
Cloudflare Tunnelの使用には基本的に料金はかかりません。
もし、ドメインを新規で購入したり、ドメイン移管を行う場合にはその手数料が別途かかることは頭に入れておいてください。
自宅に転がっている計算資源を使うのであればサーバ購入費も必要なくなるので、ほぼほぼコストゼロで始めることができます。
従来の自宅サーバ公開で詰まりやすいところ
自宅サーバを公開したい理由はいろいろあります。
- 外部に向けて小さなサービスを公開したい
- 少し重めのサービスを自分の機材で動かしたい
- CPU、メモリ、ストレージを多めに使う処理をクラウドに置きっぱなしにしたくない
- 手元のミニPCや余ったデスクトップを活用したい
クラウドに置けば、もちろん話は早いです。VPSを借り、グローバルIPをもらい、DNSを向け、必要なポートを開ければよい。管理画面も請求もまとまっていて、障害時の切り分けもしやすい。
ただし、常時起動するものは月額費用が効いてきます。小さなインスタンスならまだしも、メモリ16GB、ストレージ1TB、ある程度のCPU性能、となったり、さらにGPUも使いたいとなると、自宅にある計算資源でなんとかしたくなってくるわけです。
一方で、自宅回線で公開しようとすると、今度はネットワーク側の事情が出てきます。
- 固定IPv4アドレスがない
- ルーターでポート開放できない、または設定が面倒
- IPv4 over IPv6環境で、外部から特定ポートへ入れない
- DDNSを使っても、IP変更や証明書まわりを気にする必要がある
- 自宅のIPアドレスを直接晒したくない
ここでCloudflare Tunnelを使うと、いくつかの問題を避けられます。特に大きいのは、固定IPとルーターのポート開放を前提にしなくてよいことです。
Cloudflare Tunnelは何をしているのか
Cloudflare Tunnelでは、自宅サーバ側でcloudflaredという軽量なデーモンを動かします。
このcloudflaredが、自宅サーバからCloudflareのネットワークへ向けて接続を張ります。ポイントは、接続の向きが「外から自宅へ入ってくる」のではなく、「自宅からCloudflareへ出ていく」ことです。
従来の構成は、だいたいこうです。
利用者のブラウザ
-> インターネット
-> 自宅回線のグローバルIP
-> ルーターのポート開放
-> 自宅サーバ上のWebサービス
Cloudflare Tunnelを使うと、こうなります。
利用者のブラウザ
-> Cloudflare
-> Cloudflare Tunnel
-> 自宅サーバ上のcloudflared
-> 自宅サーバ上のWebサービス
自宅サーバは、Cloudflareへ向けたアウトバウンド接続を維持します。利用者からのリクエストはCloudflareに届き、CloudflareがTunnelを通して自宅サーバ側へ中継します。
このため、自宅ルーターで80番や443番を開ける必要がありません。自宅サーバを直接指すグローバルIPも不要です。ファイアウォールも、基本的には外からのインバウンドを閉じたまま運用できます。
Cloudflareはどこで登場するのか
Cloudflare Tunnelの記事では、Cloudflareの役割が少し混ざりやすいです。
ひとことでCloudflareと言っても、今回関係する役割は少なくとも4つあります。
- ドメインのDNSを管理する
- Webアクセスを受けるリバースプロキシになる
- Tunnelの入口になる
順番に見ていきます。
DNSプロバイダ・レジストラとしてのCloudflare
独自ドメインでサービスを公開するには、まずDNSの管理をする必要があります。
Cloudflareはドメインのレジストラとしての機能も持つため、新しくドメインを契約したり、外部レジストラから今まで使っていたドメインを移管してくることができます。
Cloudflareにドメインを移管しておくとサービス関連系がとてもスムーズになるため、おすすめします。
実際に私は国内のレジストラとAWSからドメインを移管してみましたが、思った以上にスムーズに手続きができました。 ※Cloudflareで受け入れ可能なTLDかは予め調べておく必要があります。特に、.jp系のTLDは使えないという落とし穴があります(筆者ハマり済み)
たとえば、status.example.comという名前でサービスを公開したいとします。このとき、CloudflareのDNSにstatus.example.comのレコードを作ります。
Cloudflare Tunnelでは、Tunnelを作ると<TunnelID>.cfargotunnel.comというTunnel用のサブドメインが用意されます。公開したいホスト名には、このTunnel用サブドメインへ向けたCNAMEレコードを作ります。
status.example.com CNAME <TunnelID>.cfargotunnel.com
実際にはCloudflareのダッシュボードでPublic Hostnameを追加すると、このDNSレコード作成までまとめて面倒を見てくれる場合があります。手動で作る場合も、考え方は同じです。
ひとつのTunnelに対して、複数のサブドメインやドメインをぶら下げることもできます。
blog.example.com CNAME <TunnelID>.cfargotunnel.com status.example.com CNAME <TunnelID>.cfargotunnel.com test.net CNAME <TunnelID>.cfargotunnel.com
名前は複数でも、入口になるTunnelは同じです。その先でどのローカルサービスへ流すかは、ルートの設定(Tunnel側の設定)で決めます。
リバースプロキシとしてのCloudflare
Cloudflareにオンボードしたドメインでは、CloudflareがDNSプロバイダとして名前解決を担当し、さらにリバースプロキシとしてWebリクエストを受けられます。
利用者のブラウザは、直接自宅サーバへ行くのではなく、まずCloudflareへアクセスします。Cloudflareはそのリクエストを受け、設定に応じてTunnel経由でオリジン、つまり自宅サーバ側へ流します。
この間に、Cloudflare側の各種機能も使えます。必要に応じて使用してみてください。
2026年5月時点ではデフォルトでDDos軽減機能がオンになっているようです。
Tunnelの入口としてのCloudflare
Cloudflare Tunnelでは、Cloudflare側にTunnelという永続的なオブジェクトを作ります。TunnelにはTunnelIDがあり、cloudflaredはそのTunnelに接続します。
外から見ると、利用者はhttps://status.example.comへアクセスしているだけです。裏側では、Cloudflareがそのホスト名をTunnelへ紐づけ、Tunnelを通じて自宅サーバ側のhttp://localhost:3000のようなサービスへリクエストを渡します。
これによりインターネット側の公開名と、自宅サーバ内のローカルな宛先を分けて考えられます。
https://blog.example.com -> http://localhost:8080 https://status.example.com -> http://localhost:3000 https://test.net -> http://localhost:3001
外から見えるのはCloudflare上のホスト名です。自宅サーバ側は、ローカルホストやDockerネットワーク内のサービス名で受けられます。
今回作る構成
さて、では実際にCloudflare Tunnelを利用してサービスを公開してみましょう この記事ではシンプルに、次のような構成を想定します。
example.com
blog.example.com -> 自宅サーバ上のWordPress
自宅サーバ
cloudflared
wordpress:8080
ここではexample.comを例にします。実際にはご自分の環境に合わせて読み替えを行ってください。
また、本記事は2026年5月時点での内容となります。用語、UI、仕組みはこの記事を読まれているタイミングで変更になっている可能性もありますので、ご了承いただければと思います。
手順1: Cloudflareにドメインを追加する
まずCloudflareにログインし、公開に使うドメインを追加します。
すでに他社レジストラで取得済みのドメインなら、Cloudflareのダッシュボードからドメインを追加します。Cloudflareが既存のDNSレコードをスキャンするので、必要なレコードが入っているか確認します。その後、Cloudflareから指定された2つのネームサーバを、レジストラ側の管理画面で設定します。
ネームサーバを変更すると、そのドメインのDNS問い合わせにCloudflareが答えるようになります。
利用者のDNS問い合わせ
-> Cloudflareのネームサーバ
-> Cloudflare上のDNSレコード
新しくドメインを取る場合は、Cloudflare Registrarで取得する方法もあります。この場合、最初からCloudflare側でDNSを管理できるので、レジストラ側でネームサーバを変更する手間が少なくなります。


手順2: Zero TrustでTunnelを作る
CloudflareのダッシュボードからZero Trustへ移動し、NetworksまたはTunnelsの画面で新しいTunnelを作成します。
Cloudflareのドキュメントでは、多くの用途でremotely-managed tunnelが推奨されています。これは、Tunnelの設定をCloudflare側で管理し、ダッシュボードやAPI、Terraformから扱える方式です。
Tunnel名は、自宅サーバの名前や用途が分かるものにしておくと後で楽です。
home-server homelab-main mini-pc-01



Tunnelを作ると、Cloudflareは接続用のコマンドを表示します。Linuxサーバ上でそのコマンドを実行すると、cloudflaredがCloudflareへ接続します。
(次の手順にて、Dockerコンテナでcloudflaredを起動する手順を記載しています)
この時点では、まだblog.example.comとWordPressは紐づいていません。ここではまずTunnelという通り道だけを作り、後の手順で「このホスト名に来たアクセスは、自宅サーバ上のWordPressへ流す」という設定を追加していきます。
手順3: 自宅サーバでcloudflaredを動かす
cloudflaredは、自宅サーバとCloudflareをつなぐデーモンです。インストール方法は環境によっていくつかあります。
CloudflareのダッシュボードでTunnelを作成すると、環境ごとのインストールコマンドが表示されます。基本的には、その画面に出ているコマンドを使うのが安全です。
Linuxに直接インストールする場合は、Cloudflareが案内するパッケージを入れて、サービスとして起動します。
Dockerで動かす場合は、たとえば次のような形になります。
compose.yml
services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared restart: unless-stopped command: tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN}
.envなどにTunnel tokenを入れます。
CLOUDFLARED_TOKEN=ここにCloudflare dashboardで表示されたtokenを入れる
起動すると、Cloudflare側のTunnel画面でConnectorが接続済みになります。ここまで来ると、自宅サーバとCloudflareの間にTunnelが張られています。

手順4: 公開アプリケーションルートを作る
次に、外からアクセスする名前と、自宅サーバ内のサービスを紐づけます。
今回は、自宅サーバ上のWordPressをblog.example.comで公開します。CloudflareのTunnel設定で公開アプリケーションルートを追加し、次のように設定します。
ホスト名 サブドメイン: blog ドメイン: example.com パス: 空欄 サービス タイプ: HTTP URL: wordpress:8080
Service URLは、cloudflaredから見たWordPressの宛先です。Dockerネットワーク内でwordpressというサービス名で解決できるなら、wordpress:8080を指定します。ホスト上で直接8080番に出している場合は、localhost:8080を指定します。

※今回の例では、WordPressが自宅サーバ上でwordpress:8080として到達できる前提で進めています。Docker ComposeでcloudflaredとWordPressを同じネットワークに入れている場合は、cloudflared側からhttp://wordpress:8080のようにサービス名でアクセスできる状態にしてください。
また、ホスト上で直接WordPressを動かしている場合は、http://localhost:8080のように読み替えてください。
これで、外からは次のURLでアクセスできるようになります。
https://blog.example.com
Cloudflareは上記のルート追加時に、blog.example.comがTunnelへ向くようDNSレコードを作ります。Cloudflareのドメイン→[該当ドメイン]→DNS→レコードメニューから追加されたDNSレコードを確認できます。
追加されるCNAMEの向き先はおおむね次の形になります。
blog.example.com CNAME <TunnelID>.cfargotunnel.com
このDNSレコードとTunnel自体は独立しています。DNSレコードが残っていても、Tunnelが止まっていればアクセスは成功しません。Cloudflareがエラーページを表示してくれます。

手順5: 動作確認する
ブラウザでhttps://blog.example.comへアクセスします。自宅サーバ上のWordPressが表示されれば成功です。

うまくいかない場合は、次を見ます。
- TunnelのConnectorが接続済みになっているか
- 自宅サーバ内で対象サービスが起動しているか
wordpress:8080などの宛先が正しいか(適切なプロトコルを指定しているか。ありがちなのはhttpとhttpsの差)- Dockerの場合、
cloudflaredコンテナから対象コンテナへ到達できるか - DNSレコードがCloudflare上に作られているか
cloudflaredをDockerで動かしている場合、cloudflaredコンテナとWordPressコンテナが『同じDockerネットワークに入っている』必要があります。おかしいなと思ったら、丁寧に設定を見直してみましょう。
まとめ
Cloudflare Tunnelを使うと、自宅サーバを独自ドメインで公開するハードルがかなり下がります。ドメインとの紐づけも容易に行えるため、作業自体も大幅に短縮され、運用者としてはとても便利です。
また、Cloudflareの機能を使えばアクセス制限も柔軟に行えるので、必要な範囲だけさらに絞って公開するといった運用も可能です。
もちろん、万能ではありません。アプリ自体の脆弱性はもちろんケアできませんし(これは自宅サーバに限った話ではありませんが)、可用性といった面でもクラウドサービスには劣るでしょう。
それでも、自宅に計算資源が眠っていたり、(新古問わず)ハードウェアを購入してもペイできる算段がついているならば、きっとCloudflare Tunnelはよい選択肢となるはずです。
私個人としては、自宅サーバに戻してからのほうが日々のサーバ管理が楽になりました。 性能が潤沢というのもありますし、Cloudflare Tunnelのおかげで外部に露出させている範囲がわかりやすくなったので心理的な負担も減った気がします。
皆さんもこれを機に、自宅サーバ生活を始めましょう!!
ここまでお読みいただき、ありがとうございました!
参考にした公式ドキュメント
- Cloudflare Tunnel overview
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ - Cloudflare Tunnel get started
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/ - DNS records for Cloudflare Tunnel
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/routing-to-tunnel/dns/ - Onboard a domain to Cloudflare
https://developers.cloudflare.com/fundamentals/setup/manage-domains/add-site/ - Cloudflare Registrar
https://developers.cloudflare.com/registrar/ - Cloudflare plans
https://www.cloudflare.com/plans/ - Cloudflare One account limits
https://developers.cloudflare.com/cloudflare-one/account-limits/