Cloudflare Tunnelを使って、自宅サーバをインターネットへ公開してみよう

はじめに

こんにちは! 株式会社アドグローブ ゲーム事業本部 エンジニアの九津見です。

ウェブサービスを公開しようとする場合、クラウドサービスを利用する場合が多いと思いますが、昨今では円安の影響もあり、前ほど気軽に立てるということが難しくなってきていると感じています。

比較的シンプルなデータの出し入れをする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つあります。

  1. ドメインのDNSを管理する
  2. Webアクセスを受けるリバースプロキシになる
  3. 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を管理できるので、レジストラ側でネームサーバを変更する手間が少なくなります。

ドメインをCloudflareに登録する

手順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の作成

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が張られています。

cloudflaredが接続された状態

手順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がエラーページを表示してくれます。

自動で作成されたCNAMEの例

手順5: 動作確認する

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

独自ドメインでWordpressが表示された!

うまくいかない場合は、次を見ます。

  • TunnelのConnectorが接続済みになっているか
  • 自宅サーバ内で対象サービスが起動しているか
  • wordpress:8080などの宛先が正しいか(適切なプロトコルを指定しているか。ありがちなのはhttpとhttpsの差)
  • Dockerの場合、cloudflaredコンテナから対象コンテナへ到達できるか
  • DNSレコードがCloudflare上に作られているか

cloudflaredをDockerで動かしている場合、cloudflaredコンテナとWordPressコンテナが『同じDockerネットワークに入っている』必要があります。おかしいなと思ったら、丁寧に設定を見直してみましょう。

まとめ

Cloudflare Tunnelを使うと、自宅サーバを独自ドメインで公開するハードルがかなり下がります。ドメインとの紐づけも容易に行えるため、作業自体も大幅に短縮され、運用者としてはとても便利です。

また、Cloudflareの機能を使えばアクセス制限も柔軟に行えるので、必要な範囲だけさらに絞って公開するといった運用も可能です。

もちろん、万能ではありません。アプリ自体の脆弱性はもちろんケアできませんし(これは自宅サーバに限った話ではありませんが)、可用性といった面でもクラウドサービスには劣るでしょう。

それでも、自宅に計算資源が眠っていたり、(新古問わず)ハードウェアを購入してもペイできる算段がついているならば、きっとCloudflare Tunnelはよい選択肢となるはずです。

私個人としては、自宅サーバに戻してからのほうが日々のサーバ管理が楽になりました。 性能が潤沢というのもありますし、Cloudflare Tunnelのおかげで外部に露出させている範囲がわかりやすくなったので心理的な負担も減った気がします。

皆さんもこれを機に、自宅サーバ生活を始めましょう!!

ここまでお読みいただき、ありがとうございました!

参考にした公式ドキュメント