きっかけ:VPS代が高すぎる問題
筆者はこれまで、さくらのVPS(メモリ2GB)を契約して、WordPressや自作のWebアプリを動かしていました。メモリ2GBでも特に問題なく動いていたので、しばらくはそれで十分でした。
ところが、現在開発中のサービス(PrintBuddy:ペット写真から3Dフィギュアを作るアプリ)では、背景除去や画像加工、3Dモデルの処理など、それなりにメモリを使う処理が必要になりました。さくらのVPS 2GBでは到底動かせません。
では16GBのVPSを契約するとどうなるか。月々約16,000円です。まだ収益化できていないサービスに、この固定費は痛すぎます。
一方で、自宅には10年ほど前に購入したノートPC(SSD 1TB / メモリ16GB)が眠っていました。Windowsが入っていましたが、もう使っていません。さくらのVPS 2GBで問題なく動いていたことを考えると、メモリ16GBはUbuntuサーバーとしてはかなり潤沢なスペックです。
ちなみに最近はメモリの価格が高騰していて、新しくサーバー用PCを組むのもなかなか厳しい状況です。手元にあるPCを活用できるなら、それに越したことはありません。
そこで、このノートPCにUbuntuをインストールして自宅サーバーにし、Cloudflare Tunnelで外部に公開することにしました。
この記事を読むメリット・対象読者
自宅にサーバーを置いて外部に公開したい、と思ったことはありませんか?
ただ、いざ調べてみると「固定IPの契約が必要」「ルーターのポートを開けないといけない」「セキュリティ的に大丈夫なの?」といった話が次々出てきて、結局やめてしまった人も多いのではないでしょうか。
この記事では、Cloudflare Tunnelを使って、それらの問題をまとめて解決する方法を紹介します。
この記事を読むとわかること
- 固定IPを契約せず、ルーターのポートを一つも開けずに、自宅サーバーをインターネットに公開する方法
- Cloudflare Tunnelの仕組みと、なぜこの方法が安全なのか
- Docker Composeを使った実際の構成例と、運用上の注意点
対象読者
- 個人開発をしているエンジニア・フリーランスの方
- VPS代を毎月払うのがもったいないと感じている方
- 自宅サーバーを公開したいけど、ネットワーク設定に不安がある方
- GPUを使うアプリ(AI推論、画像生成など)を公開したいが、AWSやGCPのGPUインスタンスは高額すぎるため、自宅のGPU搭載PCをサーバーとして使いたい方
自宅サーバーの公開、従来はこんなに面倒だった
自宅サーバーを外部に公開しようとすると、従来は以下のようなハードルがありました。
固定IPの契約が必要でした。プロバイダによっては月額数百〜数千円の追加料金が発生します。固定IPが使えないプロバイダもあります。
固定IPが取れない場合はDDNSの設定で代替しますが、IPアドレスが変わるたびにDNSの更新が走るため、一時的にアクセスできなくなるタイミングが発生します。
さらにルーターのポート開放が必要です。80番や443番をルーターで開けて、自宅サーバーに転送する設定をしなければなりません。これは「自宅のネットワークに外部から直接入れる穴を開ける」ということなので、セキュリティリスクが伴います。設定を間違えると、意図しないサービスが外部に晒される可能性もあります。
正直なところ、個人開発者がこのあたりを全部正しく設定・維持するのはかなり大変です。
Cloudflare Tunnelとは?なぜこれで解決するのか
Cloudflare Tunnelは、発想を逆転させることでこれらの問題を解決しています。
従来の方式は「外から自宅に接続できるように穴を開ける」というものでした。Cloudflare Tunnelは違います。自宅サーバーからCloudflareに向かって接続を張るのです。
仕組みはこうです。
- 自宅サーバー上で
cloudflaredというデーモンを起動する -
cloudflaredがCloudflareのエッジサーバーに対して、外向きの接続を確立する - ユーザーがあなたのドメインにアクセスすると、Cloudflareがそのリクエストを受け取り、確立済みのトンネル経由で自宅サーバーに転送する
ポイントは、**自宅サーバーからCloudflareへの接続は外向き(アウトバウンド)**だということです。これにより、以下のすべてが不要になります。
- 固定IP → 不要。接続はサーバー側から張るので、IPアドレスが変わっても問題ない
- ポート開放 → 不要。外部から自宅ネットワークへの穴を一切開けない
- DDNS → 不要。DNSはCloudflare側で管理される
しかも、Cloudflare Tunnelは無料で使えます。
さらに、Cloudflareを経由することで、以下のメリットも自動的についてきます。
- DDoS攻撃の自動遮断:Cloudflareのエッジで不正なトラフィックをブロックしてくれる。自宅サーバーに攻撃が到達する前に弾いてくれるので、個人運用でも安心感がある
- 自宅サーバーのIPアドレスが隠蔽される:すべてのアクセスはCloudflareを経由するため、自宅のIPアドレスが外部に露出しない。これはセキュリティ上かなり大きい
- CDNキャッシュ:静的ファイル(画像、CSS、JSなど)はCloudflareのエッジサーバーにキャッシュされるため、自宅サーバーの負荷軽減とレスポンス速度の向上が見込める
- Cloudflare Access(Zero Trust)との連携:管理画面など特定のページにGoogleログインなどの認証を追加できる。アプリ側で認証機能を作らなくても、Cloudflare側で簡単にアクセス制限をかけられる
自宅サーバーの公開方法としてだけでなく、セキュリティ・パフォーマンスの面でもメリットが大きいのがCloudflare Tunnelの強みです。
セットアップの前に:環境差でつまづいたらAIに聞こう
この先の手順は、筆者の環境(Ubuntu 24.04 / Docker Compose)での例です。基本的な流れはどの環境でも同じですが、OSやDockerのバージョン、ネットワーク構成によって細部が変わることがあります。
また、「自宅サーバーで何をしたいか」も人によって違います。Webアプリの公開、APIサーバー、ファイルサーバー、GPU推論サーバーなど、やりたいことが違えば最適な構成も変わります。
手順通りに進めてうまくいかない場合は、Claude(Claude Code / Web版)やChatGPTに自分の環境とエラー内容を伝えて聞くのがおすすめです。
- エラーが出たら、画面のキャプチャをそのままAIに貼り付けて聞くのが一番早い
- 「この設定で自分の環境に合ってる?」という確認にも使える
- 自分のやりたいことを伝えれば、この記事の構成をベースにしたカスタマイズ案も出してくれる
実際にセットアップしてみる
前提条件
- Cloudflareのアカウントを持っていること
- Cloudflareにドメインが登録されていること(Cloudflare Registrarで取得するか、他社で取得したドメインのネームサーバーをCloudflareに向ける)
- 自宅サーバーにDockerとDocker Composeが入っていること
ステップ1:Cloudflareダッシュボードでトンネルを作成する
- Cloudflare Zero Trustにアクセスする
- 左メニューから Networks → Tunnels を選択
- Create a tunnel をクリック
- Tunnel名を入力する(例:
my-home-server) - 作成後、トンネルのトークンが表示されるので、これをコピーしておく
ステップ2:cloudflaredをDockerコンテナとして動かす
docker-compose.ymlに以下のようなサービスを追加します。
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN}
.envファイルにトークンを設定します。command内の${CLOUDFLARED_TOKEN}はDocker Composeが.envから自動で展開してくれます。
CLOUDFLARED_TOKEN=eyJhIjoixxxxxxxxxxxxxxxx...
起動します。
docker compose up -d cloudflared
docker compose logs cloudflaredでログを確認し、Connection registeredのようなメッセージが出ていれば、トンネルの確立は成功です。
ステップ3:Public Hostnameを設定する
Cloudflareダッシュボードのトンネル設定画面で、Public Hostnameを追加します。
| 項目 | 設定例 |
|---|---|
| Subdomain |
app(任意) |
| Domain | yourdomain.com |
| Type | HTTP |
| URL |
nginx:80(Docker内のサービス名とポート) |
ここでのURLは、cloudflaredコンテナから見た接続先を指定します。同じDockerネットワーク内にいるNginxやアプリケーションコンテナのサービス名を使えるのがポイントです。
設定を保存すると、CloudflareのDNSにCNAMEレコードが自動で作成されます。
ステップ4:動作確認
ブラウザで https://app.yourdomain.com にアクセスして、自宅サーバー上のサービスが表示されれば成功です。
SSL証明書もCloudflareが自動で処理してくれるので、Let's Encryptの設定も不要です。
実運用のポイント
セットアップ自体はシンプルですが、実際に運用してみるといくつか知っておいた方がいいことがあります。
筆者はこの構成で、自作のWebアプリを複数本番運用しています(運用開始から数ヶ月経過)。以下はその中で得た知見です。
複数サービスを1つのトンネルで公開する
1つのトンネルで複数のサービスを公開できます。CloudflareダッシュボードでPublic Hostnameを複数登録するだけです。
| Hostname | 転送先 |
|---|---|
app.yourdomain.com |
http://webapp:3000 |
api.yourdomain.com |
http://api-server:8000 |
admin.yourdomain.com |
http://admin-panel:8080 |
サブドメインごとに異なるDockerコンテナに振り分けられるので、1台のサーバーで複数サービスを運用する場合に便利です。
Dockerネットワークの構成
cloudflaredコンテナが他のサービスコンテナと通信できるように、同じDockerネットワークに入れる必要があります。
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN}
networks:
- app-network
webapp:
image: your-webapp:latest
container_name: webapp
networks:
- app-network
networks:
app-network:
driver: bridge
複数のdocker-compose.ymlでサービスを管理している場合は、外部ネットワーク(external: true)を使って共有する方法もあります。
SSL/TLSの設定
CloudflareダッシュボードのSSL/TLS設定で暗号化モードを選べますが、Tunnel利用時は少し事情が異なります。
通常のCloudflareプロキシでは、Cloudflare↔オリジン間はインターネットを経由するため、暗号化モードの選択が重要です。しかしTunnel経由の場合、Cloudflare↔自宅サーバー間の通信はトンネル自体で暗号化されているため、オリジン側でHTTPのままでも経路上の盗聴リスクは低いです。
- Flexible:オリジン側はHTTPのまま。Tunnel利用なら実用上問題ないケースが多い
- Full (Strict):オリジン側にも証明書を設定。より厳密なセキュリティが必要な場合に
個人開発であればFlexibleで運用して問題ないケースが多いですが、要件に応じて選んでください。
トンネルが落ちた場合の挙動
docker-compose.ymlでrestart: unless-stoppedを設定しておけば、cloudflaredコンテナが異常終了しても自動で再起動します。
サーバー自体が再起動した場合も、Docker Composeのサービスが自動起動するようにしておけば、特に何もしなくてもトンネルが復旧します。
# サーバー起動時にDockerサービスが自動起動するようにする
sudo systemctl enable docker
長期間の運用でcloudflaredのイメージが古くなった場合は、定期的にイメージを更新してください。
docker compose pull cloudflared
docker compose up -d cloudflared
コスト
改めて整理すると、この構成のランニングコストは以下の通りです。
- Cloudflare Tunnel:無料
- Cloudflareのドメイン管理・DNS:無料
- ドメイン取得・更新費用:年間数ドル〜十数ドル(ドメインの種類による)
- サーバー:自宅にある既存PCやミニPCを使えば追加費用なし
- 電気代:サーバーの消費電力分のみ
VPSを使う場合の月額数百〜数千円と比べると、大幅にコストを抑えられます。
制約・デメリットも知っておく
いいことばかり書いてきましたが、制約もあります。導入前に把握しておいてください。
- 無料プランのアップロードサイズ制限(100MB):Cloudflare経由でアップロードできるファイルサイズは、無料プランでは1リクエストあたり100MBが上限です。大きなファイルを扱うサービスでは引っかかる可能性があります
- Cloudflareへの依存:すべてのトラフィックがCloudflareを経由するため、Cloudflare側に障害が起きると自分のサービスも止まります。単一障害点になるという点は認識しておく必要があります
- 大容量コンテンツの配信制限:Cloudflareの利用規約上、無料プランでの大量の動画配信など、過度なトラフィックはNGとされている場合があります。用途によっては規約を確認してください
- 自宅回線がボトルネックになる:アクセスが増えた場合、自宅のインターネット回線(特に上り速度)がそのままサービスの速度制限になります。マンションの共有回線などでは特に注意が必要です
- 自宅インフラに依存する:停電、ルーターの再起動、プロバイダの障害がそのままサービス停止に直結します。VPSやクラウドのようなインフラ冗長性はありません
個人開発や小規模サービスであれば、これらの制約が致命的になることは少ないですが、「VPSと完全に同じ可用性が得られるわけではない」という点は理解した上で使うのが良いです。
まとめ
Cloudflare Tunnelを使えば、固定IPの契約もポート開放も不要で、自宅サーバーを安全に外部公開できます。Docker Composeとの相性も良く、セットアップも比較的シンプルです。
以下のような方には特におすすめです。
- 個人開発のアプリを安くホスティングしたい
- VPS代を節約したい
- 自宅の余ったPCを開発用サーバーとして活用したい
- ネットワーク設定を最小限にして、アプリ開発に集中したい
次回の第2部では、この自宅サーバー上にGitHub Actions(self-hosted runner)を使ったCI/CDパイプラインを構築する方法を紹介します。ローカルで開発して、git pushしてマージするだけで、自宅サーバーに自動デプロイされる仕組みです。