外部公開(トンネル)
roji は既定ではループバックアドレスでしか待ち受けない(
設定ガイドの
bind を参照)。外から開発機に届かせたい
場面(webhook の受信、作りかけのアプリを人に見せる)のために、Cloudflare
Tunnel を通して選んだルートだけを公開できる。
bind を広げるのとは違い、公開の単位はコンテナごとで、ダッシュボードと
その API は公開されない。
必要なもの
- Cloudflare アカウントと、そこに登録済みのゾーン(
example.comなど) - cloudflared が PATH にあること。roji は cloudflared を子プロセスとして実行する
cloudflared tunnel login # ブラウザが開き ~/.cloudflared/cert.pem を作る
cloudflared tunnel create roji # named tunnel を作る設定
~/.config/roji/config.yaml に tunnel: ブロックを足す。
tunnel:
domain: example.com # Cloudflare 上のゾーン
name: roji # cloudflared tunnel create で作った named tunnel
port: 8080 # トンネル専用リスナー(127.0.0.1 固定、既定 8080)
auto_start: false # roji が cloudflared を起動するかdomain と name の両方が揃ったときだけトンネルが有効になる。環境変数は
無く、設定ファイル専用。
auto_start: true にすると roji が cloudflared を起動し、roji の終了時に
停止する。false のままなら、リスナーだけが開くので cloudflared tunnel run roji を自分で回す。
公開するルートを選ぶ
コンテナに roji.tunnel ラベルを付ける。付けたものだけが外に出る。
# docker-compose.yml
services:
api:
labels:
- "roji.tunnel=true"true / 1 / yes / on が肯定として扱われ、それ以外(ラベルなし、空、
書き間違い)はすべて非公開になる。roji はネットワーク上のコンテナをラベル
無しで拾うので、既定で公開すると全部が外に出てしまう。だから明示的な
オプトインにしてある。
DNS レコード
*.{domain} をトンネルに向ける設定は手動で行う。roji に Cloudflare の API
トークンを持たせない方針のため、この 1 手だけは roji がやらない。
cloudflared tunnel route dns roji "*.example.com"Cloudflare のダッシュボードから <uuid>.cfargotunnel.com への CNAME を
作っても同じ。
ドメインは 1 階層に収める
Cloudflare の Universal SSL がカバーするのは example.com と
*.example.com だけ。tunnel.example.com のような 2 階層の名前にすると
*.tunnel.example.com の証明書が必要になり、有償の Advanced Certificate
Manager が要る。設定バリデーションが警告を出す。
ホスト名の対応
ローカル名の接尾辞を入れ替えたものが公開名になる。
| ローカル | 公開 |
|---|---|
web.dev.localhost | web.example.com |
api.dev.localhost | api.example.com |
バックエンドに渡される Host はローカル名のまま。開発サーバーの許可
ホスト設定(Vite の server.allowedHosts など)は、いつもどおり
*.dev.localhost を書いておけばよい。
公開されないもの
トンネル経由のリクエストは、通常のリスナーとは別のポートに届く。 cloudflared は 127.0.0.1 から接続してくるので、リクエストの中身では ローカルのブラウザと区別がつかない。区別できるのは到達したポートだけで、 その分離を使って以下を落としている。
/_api/*と/_assets/*。パスだけで無条件に 404 になり、設定では 開けられない。/_api/projects/{name}/upは無認証でコンテナを起動でき、/_api/logsはリクエストログを読める- ダッシュボードのホスト名とベースドメイン
roji.tunnelの無い Docker ルート- 静的サイト(
static_sites:にオプトインの綴りが無いため、現状すべて非公開)
拒否はどの理由でも同じ素の 404 を返す。理由ごとに文言を分けると、どの ホスト名が存在するかを外に教えてしまうため。
確認する
roji doctorcloudflared の導入、ログイン状態、named tunnel の存在を確認する。DNS レコードだけは roji から検証できないので、案内の表示に留まる。
ダッシュボードでは、公開中のルートに 🌐 バッジと公開 URL が出る。ラベルを
付けても tunnel: を設定していなければ何も公開されないので、バッジも
出ない。
入れていないもの
roji tunnel start/stop/statusコマンド。auto_start: falseのときはcloudflared tunnel runを自分で回す前提- 静的サイトの公開
- cloudflared がクラッシュした後の自動再起動。roji はプロセスマネージャでは ないので、落ちたことをログに出して放置する。認証に失敗し続けるトンネルが 黙って再試行を繰り返す方が困るため
- Cloudflare API トークンによる DNS レコードの自動作成