mcpField
C
cloudflare-tunnel-publish

cloudflare-tunnel-publish

github.com/starchild-ai-agentクラウド・DevOps3093 回インストール6 日前に更新
リポジトリ

cloudflare-tunnel-publish について

Cloudflare Tunnelを使い、ローカルのHTTPサービスを独自ドメインで公開するワークフロー用スキルです。パブリックIPや受信ポートの開放は不要で、ドメインとトークンの準備を案内し、トンネルやDNSの設定、起動、URL検証を自動化します。

主な機能

  1. 01ローカルポートを公開ホスト名に接続
  2. 02Cloudflare TunnelとDNSの設定
  3. 03稼働中のトンネル再利用または新規作成
  4. 04公開URLの起動と検証
  5. 05複数のサブドメインでトンネルを共有

活用シーン

  1. 01ローカルで動くWebサービスの公開
  2. 02Starchildのプレビューを外部公開
  3. 03複数のサブドメインを1つのトンネルに接続

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill cloudflare-tunnel-publish

インストール後、Claude Code で/cloudflare-tunnel-publishを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
cf_api.py
check_status.py
keepalive.sh
run_tunnel.sh
setup.py
teardown.py
verify.py

詳細

このスキルが行うこと

ローカルポートで実行されているサービス(デフォルトでは Starchild のプレビューですが、任意の HTTP サービスで動作します)を、Cloudflare Tunnel を使って app.userdomain.com で世界中からアクセスできるようにします。パブリック IP は不要、インバウンドポートを開く必要もなく、SSL も無料です。

フローにおける 2 つの役割:

  • ユーザーが手動で行うこと(必須、自動化できません): Cloudflare アカウントの作成、ドメインの購入または Cloudflare への移管、API トークンの作成。
  • エージェントが自動で行うこと(このスキル): トークンの検証、ゾーンの選択、トンネルの作成、イングレスの設定、DNS の作成、cloudflared のインストールと起動、公開 URL が機能することの確認。

想定する対象読者

ユーザーを初心者として扱ってください。Cloudflare を使ったことがないかもしれません。一度に 1 つのマイクロステップずつ案内し、確認を待ってから次に進んでください。10 ステップの計画を丸ごと投げつけて消えるのはやめてください。

ワークフロー

フェーズ 0 — 段取りを整える(1 メッセージ)

これから何が起こるのかを平易な言葉で、4 つのフェーズに分けてユーザーに伝えてください:

  1. Cloudflare アカウントを登録し、ドメインを追加します(手動、約 5 分)
  2. API トークンを作成し、安全にあなたへ渡します(手動、約 2 分)
  3. あなたがトンネルと DNS を構築し、起動します(自動、約 1 分)
  4. 一緒に URL をテストします(自動)

質問してください: 「Cloudflare にすでにドメインをお持ちですか、それともゼロから始める必要がありますか?」 回答に応じて分岐してください。

フェーズ 1 — ユーザーが Cloudflare でドメインを取得できるようにする

まだ持っていない場合:

  • https://dash.cloudflare.com/sign-up にアクセスして登録するよう案内してください
  • 次に https://dash.cloudflare.com/?to=/:account/domains でドメインを購入する(Cloudflare は .com / .net / .org / .io / .dev / .app などをレジストリ原価で販売しています)、または既存のドメインを追加してネームサーバーを変更してください
  • 続行する前に、ユーザーが「ドメインが Cloudflare で有効になっている」と確認するのを待ってください

初心者向けに共有するヒント: 「Cloudflare ダッシュボードでドメインのステータスが Active と表示されていれば、続行して問題ありません。」

すでに持っている場合: フェーズ 2 にスキップしてください。

フェーズ 2 — API トークンを作成する

次の正確なリンクをユーザーに送ってください(可能な場合は適切な権限が事前入力され、ユーザーが手動で構築することもできます):

https://dash.cloudflare.com/profile/api-tokens → Create Token → Create Custom Token

必要な権限(次の 3 つを追加するよう伝えてください):

  • Account → Cloudflare Tunnel → Edit
  • Zone → DNS → Edit
  • Zone → Zone → Read

Account Resources: ユーザーのアカウント。Zone Resources: Include All zones(または特定のドメイン)。TTL: デフォルトのままにします。

ユーザーが Continue to summary → Create Token をクリックすると、Cloudflare はトークンを一度だけ表示します。次のように伝えてください: チャットに貼り付けないでください。

フェーズ 3 — トークンを安全に受け取る

request_env_input を次の内容で呼び出してください:

env_vars=[{"key": "CLOUDFLARE_API_TOKEN", "label": "Cloudflare API Token", "required": true}]
reason="Used to create the tunnel and DNS record on your domain. Stored locally in workspace/.env, never echoed in chat."

ユーザーが安全なポップアップ経由で送信するのを待ちます。すぐに送信しない場合でもリトライループしないでください — ただ待ってください。

フェーズ 4 — トークンを検証し、ゾーンを選択する

python3 skills/cloudflare-tunnel-publish/scripts/verify.py を実行してください。次の内容が出力されます:

  • トークンの有効性
  • ユーザーの account_id(workspace/.cf_state.json に保存されます)
  • アカウント上のすべてのゾーン(ドメイン)

複数のゾーンがある場合は、どのドメインを使うかユーザーに尋ねてください。zone_id と zone_name を状態に保存してください。

フェーズ 5 — 何を公開するかを決める

ユーザーに 2 つのことを尋ねてください:

  1. サブドメイン(例: app、demo、www)→ 最終的なホスト名は <sub>.<zone_name> になります。Apex ドメイン(@)も使用できます。
  2. ローカルポート(例: 8080、3000)。「私の Starchild プレビュー」と言った場合は、cat /data/previews.json 2>/dev/null を実行して既存のプレビューのポートを調べてください。そうでなければ明示的に尋ねてください。

デフォルトのサービス URL: http://localhost:<port>。

フェーズ 6 — トンネルを構築する(自動化)

python3 skills/cloudflare-tunnel-publish/scripts/setup.py --hostname <full_hostname> --port <port> を実行します。

トンネルの再利用がデフォルトです。 アカウント上に正常なトンネルがすでに存在する場合、setup.py は新しいトンネルを作成するのではなく、そのトンネルの ingress に新しいホスト名を追加し、DNS CNAME をそこに向けます。1 つのトンネル = 1 つの cloudflared プロセス = 1 つのキープアライブ監視です。サイトごとに新しいトンネルを作成すると、面倒を見なければならないプロセスが N 個になり、気づかないうちに停止する原因が N 通りできることになります(まさにこれが問題の発端となったバグです。2 つ目のトンネルの cloudflared が停止しても、監視は最初のトンネルしか認識していなかったため、誰も気づきませんでした)。

--new-tunnel を渡すのは、トラフィックを分離する理由がある場合(例: 1 つのサイトのトラフィック量が非常に多く、共有エッジ接続を飽和させてしまう場合)だけにしてください。

スクリプトは次の順序で処理を行います:

  1. 正常なトンネルが存在する場合は再利用する(存在しない場合は starchild-<hostname> という名前で作成するか、--new-tunnel で新しいトンネルの作成を強制する)
  2. トンネルの実行トークン(cloudflared の起動に使用する長い base64 文字列)を取得する
  3. ingress 設定を PUT する: <hostname> → http://localhost:<port> を既存の ingress ルールにマージする(他のホスト名は保持する)、フォールバックは 404
  4. CNAME DNS レコードを作成する: <hostname> → <tunnel_id>.cfargotunnel.com、proxied = true
  5. workspace/.cf_state.json の sites 配列にサイトを追加する(マルチサイト対応 — 後述の「複数サイト」を参照)

同じ名前のトンネルが存在する場合は、エラーにせず再利用します。

フェーズ 7 — cloudflared を起動する

bash skills/cloudflare-tunnel-publish/scripts/keepalive.sh を実行します — これがサイトを起動する正規の方法です。keepalive.sh は起動と復旧を担う唯一の頭脳です(後述の「稼働させ続ける」を参照): .cf_state.json を読み取り、アプリ(--app-cmd を記録した場合)とトンネルを起動し、公開 URL を検証します。run_tunnel.sh は keepalive.sh が呼び出す、トンネル専用のより低レベルなランチャーです — 存在しない場合は cloudflared を workspace/bin/ にダウンロードし、.cf_state.json から run_token を読み取り、cloudflared tunnel run を実行します。

サイトが稼働していることをユーザーに伝えます。永続性のために起動時とスケジュールに組み込むのは、同じ keepalive.sh です — 別のスターターを自作しないでください。

フェーズ 8 — 検証する

⚠️ コンテナの curl https://<hostname> を直接使用しないでください — コンテナのリゾルバーは新しいドメインの古い NXDOMAIN をキャッシュし、誤った結果を返します。常に DoH 経由で検証してください:

curl -sS "https://dns.google/resolve?name=<hostname>&type=A" | python3 -m json.tool

考えられる結果は 3 つあります:

  1. Status: 0 + Answer に IP → 稼働中です。このとき curl -I https://<hostname> は 200/301/302 を返すはずです。ユーザーに URL を伝えます。🎉
  2. Status: 3(NXDOMAIN)+ Authority = TLD レジストリの NS(例: ns.trs-dns.com) → TLD レジストリが新しいドメインをまだ反映していません。 ユーザーに伝えます: 設定は 100% 完了しており、30〜60 分待って(新規登録ドメインは最大 24 時間かかることがあります)再試行してください。ポーリングを続けないでください — ユーザー自身のデバイスで確認してもらいましょう。
  3. トンネルログにエラーが表示される(bash_process(action='log', session_id=...) を確認) → 実際の設定バグです。よくある原因: ingress が正しいポートを指していない、ローカルサービスが実行されていない、CNAME のターゲットが間違っている。

判断ルール

  • ユーザーが「自分のサービスは Starchild ではなく自分のラップトップ上にある」と言った場合 → フローはまったく同じですが、フェーズ 7 はこのコンテナ内ではなく、ユーザーのラップトップ上で実行する必要があります。ユーザーの OS に応じた同等のインストールコマンドを提示してください:

    • macOS: brew install cloudflared && cloudflared tunnel run --token <TOKEN>
    • Linux/Windows: https://github.com/cloudflare/cloudflared/releases/latest へのリンク 必要に応じて request_env_input 経由で run_token を送信するか、あるいは一度だけ出力してユーザーにコピーしてもらってください(ユーザー自身のマシンと共有するのは安全ですが、チャットに貼り戻さないでください)。
  • ユーザーが複数のサブドメインを希望する場合 → 同じトンネルを再利用します。すべてのホスト名を列挙した新しい ingress 設定を PUT し、ホスト名ごとに CNAME を 1 つ作成します。これは現在のデフォルトの動作です — サブドメインごとに setup.py を実行するだけで、既存トンネルの ingress にマージされます。

  • ユーザーが削除を希望する場合 → python3 skills/cloudflare-tunnel-publish/scripts/teardown.py を実行します(DNS + トンネルを削除し、ローカルの cloudflared プロセスを終了します)。

注意点(⚠️ すべて実際の実行で確認済み)

トークン / API
  • Cloudflare-Tunnel:Edit では /accounts の一覧取得は許可されません。 有効なトークンであっても GET /accounts を呼び出すと空のリストが返ります。解決策: 任意のゾーンに埋め込まれている account.id フィールドから account_id を導出します — verify.py はすでにこれを行っています。これを修正するためだけに Account:Account Settings:Read を追加しないでください。ゾーンのトリックのほうがクリーンです。
  • GET /accounts/{id}/cfd_tunnel/{tunnel_id}/token から取得できる「run token」は、cloudflared tunnel run --token が消費するものです。以下と混同しないでください:
    • tunnel secret — レガシーのローカル管理トンネルにのみ関連します(私たちは使用しません)
    • API Token — api.cloudflare.com を呼び出すために使用します
トンネル / Ingress
  • CNAME のターゲットは <tunnel_id>.cfargotunnel.com でなければならず、トンネル名ではありません。
  • リモート管理トンネル(config_src: "cloudflare")は、ローカルの config.yml ではなく API 設定エンドポイント経由でルーティングします。ローカルの config.yml を生成しないでください。
  • API 経由でトンネルを作成するには、config_src=cloudflare であっても tunnel_secret フィールド(32 ランダムバイト、base64)が必要です。setup.py はこれを自動的に生成します。
Universal SSL プロビジョニングの遅延 — もう一つの大きな罠

DNS が伝播した後でも、ユーザーはブラウザで ERR_SSL_VERSION_OR_CIPHER_MISMATCH に遭遇することがあります。これはバグではありません — Cloudflare が新しいホスト名の Universal SSL 証明書をまだ発行していないのです。

診断(コンテナから実行 — 認証不要):

echo | timeout 10 openssl s_client -connect <hostname>:443 -servername <hostname> 2>&1 | grep -E "(handshake|peer certificate|Cipher is)"
  • no peer certificate available + handshake failure → 証明書がまだ発行されていない ⏳
  • 実際の証明書が返される → 動作している ✅

タイミング:

  • 以前に証明書がある確立済みゾーン: 通常 5 分未満
  • まったく新しいドメイン: 15 分~24 時間(DNS 検証 + CA 署名 + エッジ伝播)

ユーザーに伝えること:

  1. dash.cloudflare.com → <domain> → SSL/TLS → Edge Certificates を開く
  2. *.<domain>, <domain> のような行を探し、ステータスを確認する:
    • Active → 完了、ブラウザを更新
    • Pending Validation / Initializing → 待つ
  3. SSL/TLS → Overview → Encryption mode が Full(Flexible でも Full Strict でもない)であることを確認する。トンネルは常にオリジンへ HTTPS を運ぶため、Full が適切な組み合わせです。

やってはいけないこと: ユーザーに Advanced Certificate($$$)の追加や DNS の変更を指示しないこと — どちらも役に立ちません。ただ待つだけです。

DNS 伝播 — 大きな罠

新規登録ドメインは、Cloudflare ダッシュボードで即座に「Active」と表示されても、グローバル TLD レジストリ全体に伝播するまで 30 分~2 時間(時には最大 24 時間)かかります。 症状:

  • dig @1.1.1.1 yourdomain.com NS が NXDOMAIN(Status=3)を返す
  • Authority セクションに Cloudflare の NS ではなく、TLD のレジストリ NS(例: Tucows 経由の .fun なら ns.trs-dns.com)が表示される
  • cloudflared トンネルは接続されて正常なのに、https://yourdomain.com が DNS 解決失敗を返す

これはスキルのバグではありません — TLD レジストリの同期遅延です。 以下の診断スニペットを使って、実際の問題と区別してください。ユーザーに伝えること: 「設定は完了しています。30~60 分待ってから再試行してください。こちら側でやることはもうありません。」

コンテナ DNS — 偽陰性

Starchild コンテナの内部からテストする場合、コンテナのローカルリゾルバーが新しいドメインを認識するまでに数時間かかることがあります。常にパブリック DoH でクロスチェックしてください:

curl -sS "https://dns.google/resolve?name=hello.example.com&type=A" | python3 -m json.tool
  • Status: 0 + IP を含む Answer 配列 → 正常に動作 ✅
  • Status: 3(NXDOMAIN)+ Authority: ns.trs-dns.com(または同様のレジストリ NS)→ TLD の伝播が保留中 ⏳
  • Status: 0 だが Answer がない → CNAME は存在するが Cloudflare のオレンジクラウドがまだルーティングしていない → 30 秒待つ

稼働させ続ける — 1 つのスクリプト、2 つのトリガー

ここがエージェントが間違えやすい部分です。「公開する」のは簡単ですが、トンネルサイトを数週間にわたって稼働させ続けることが本当の仕事です。Starchild コンテナは予告なく再起動し(プラットフォームの更新、OOM、マイグレーション、ユーザーによる再起動)、cloudflared もまたコンテナが稼働し続けている間に途中で勝手に停止します(ネットワークの一時的な不具合、エッジのリセット、QUIC の障害)。どちらが起きても、何かがプロセスを再起動するまで https://yourdomain.com は 502 / 521 / 530 / 1033 を返し続けます。DNS と Cloudflare 側のトンネル設定は存続します(Cloudflare のサーバー上に存在するため)— 再起動が必要なのはローカルプロセスだけです。

設計:1 つの冪等なリカバリーブレイン(scripts/keepalive.sh)を 2 つのトリガーから呼び出す。 プロジェクトごとにスターター/ヒーラースクリプトを書かないでください — そうすると 2 つのコピーが乖離していきます。keepalive.sh はこのスキルに同梱されており、汎用的です:.cf_state.json から hostname、port、app_cmd、app_dir を読み取るので、同じファイルがどのドメインでも機能します。呼び出すエージェントはプロジェクト固有のシェルを一切書く必要がありません。

keepalive.sh が毎回の実行で行うこと:

  1. パブリック URL をプローブする(PID だけでなく到達可能性 — cloudflared プロセスは生きていても切断されていることがあります)。
  2. 正常 → 1 行ログを出力し、サイレントに終了。
  3. ダウン → 診断:ローカルアプリのポートが閉じている → アプリ(app_cmd 経由)およびトンネルを再起動。トンネルだけが死んでいる → トンネルのみ再起動。その後、数回のリトライで再検証(コールドスタートのウォームアップをカバー)。
  4. 状態遷移時のみレポート(run/keepalive.state で追跡):新たに復旧した、または新たに失敗した場合は 1 行出力。定常状態(正常、または既にダウンと認識済み)はサイレント。これにより、スケジュールされたタスクはシグナルを送るだけで、スパムにはなりません。
ステップ 1 — アプリの起動方法を記録する(セットアップ時)

keepalive がトンネルだけでなくアプリも再起動できるように、--app-cmd / --app-dir を setup.py に渡します:

python3 setup.py --hostname app.example.com --port 8765 \
    --app-cmd "python3 server.py" --app-dir projects/myapp

--app-cmd を省略すると、keepalive はトンネルのみを保護し、クラッシュしたアプリを復旧できません。アプリが別の場所で監視されていない限り、必ず記録してください。

ステップ 2 — サイトを起動する
bash skills/cloudflare-tunnel-publish/scripts/keepalive.sh

冪等:ダウンしているものを起動し、正常時は何もしません。

ステップ 3 — コンテナの再起動を乗り切る(ブートトリガー)

keepalive を workspace/setup.sh に追加します(コンテナの起動ごとに実行されます):

# Bring the tunnel site back after a restart. keepalive.sh only READS
# .cf_state.json — no Cloudflare API call, no token needed at boot.
if [ -f /data/workspace/.cf_state.json ]; then
  bash /data/workspace/skills/cloudflare-tunnel-publish/scripts/keepalive.sh &
  disown
fi

🚫 setup.py を絶対に setup.sh に入れないでください。 setup.py は設定時用です:Cloudflare API を呼び出し、run_token をローテーションする可能性があり、.cf_state.json を上書きします。起動のたびに実行するのは無駄で、レート制限に達する可能性があり、API トークンが削除されていると壊れ、動作中の設定を変更する可能性があります。起動時は状態を読み取るだけにすべきです — まさにそれが keepalive.sh の役割です。「setup」という名前が「setup.sh」に入れたくなりますが、こらえてください。

ステップ 4 — 途中でのプロセス死を乗り切る(ウォッチドッグトリガー)

同じスクリプトを安価な command モードのタスクとしてスケジュールします。1 つのスケジュールですべてのサイトを保護できます — keepalive.sh は .cf_state.json 内のすべてのサイトを 1 回のパスで反復処理するので、サイトごとのウォッチドッグは不要です:

scheduled_task(action="schedule",
  schedule="every 2 minutes",
  command="cd /data/workspace && bash skills/cloudflare-tunnel-publish/scripts/keepalive.sh",
  title="cloudflare tunnel keepalive (all sites)")
  • cd /data/workspace && を付けた相対コマンドを使用してください。絶対パス /data/workspace/... はスケジューラーによって存在しない /data/skills/... に正規化されることがあり(workspace/ セグメントが削除されます)、毎回の実行がサイレントに失敗します。cd + 相対パスなら影響を受けません。(実際の実行で確認済み。)
  • deliver はデフォルトのままにしてください。そうすれば遷移時のみのアラートが実際にユーザーに届きます。keepalive は正常実行時は既にサイレントなので、抑制すべきスパムはありません — そして本当の障害はあなたに通知されるべきです。
  • 間隔は正規化されることがあります(例:「every 2 minutes」→ 3 分)— 問題ありません。
耐久性を検証する(「安定している」と主張する前に、これをすべて行ってください)
# 1. start + idempotency
bash skills/cloudflare-tunnel-publish/scripts/keepalive.sh   # brings up
bash skills/cloudflare-tunnel-publish/scripts/keepalive.sh   # silent no-op
tail -5 logs/keepalive.log                                   # ok https://...
# 2. boot wired
grep keepalive setup.sh
# 3. watchdog registered + command stored correctly (relative path!)
#    scheduled_task(action="list")

setup.sh を編集しただけで「長期的に安定している」と主張しないでください。 それでは再起動には対応できますが、稼働中の停止には対応できません。両方のトリガー(起動時 + スケジュール)が keepalive.sh を指していること、および初回実行で ok https://... がログに記録されたことを確認してください。

ポートの衝突はサイレント障害です。 他のワークスペースプロジェクトがすでに一般的なポート(8000/8080/8765)を占有している可能性があります。アプリの bind() が Address already in use で失敗するとアプリは終了しますが、curl localhost:<port> は依然として 200 を返します — それは他の誰かのアプリが応答しているのです。プロジェクト固有の高いポートを使用し、返ってくるページが自分のコンテンツであることを確認してください(curl https://yourdomain.com | head)。単に 200 が返るかどうかだけで判断しないでください。

ユーザーに明確に伝えてください:

🔔 你的站点跑在容器里。容器可能因更新/内存/迁移随时重启,隧道进程偶尔也会自己掉线(域名变 502/521/530/1033)。我已经把一个自愈脚本写进了 workspace/setup.sh(开机自动拉起)并设了每几分钟一次的巡检(掉线自动重拉、恢复/失败才通知你)。两层都指向同一个脚本,你基本不用管。真打不开时让我看一眼 logs/keepalive.log 和 logs/cloudflared.log 就能定位。

プランの制限
  • 無料プランで十分です。 アップセルは不要です。
  • 無料プランでは公開でプロキシできるのはポート 80/443 のみです — これは私たちには関係ありません。トンネルは常に 443 を世界に公開するからです。localhost:<port> は何でもかまいません。

状態ファイルのフォーマット

workspace/.cf_state.json は複数のサイトをサポートしています。正規の保存先は sites 配列です。フラットなトップレベルフィールドは後方互換のために保持されており、常に最後に設定されたサイトを反映します:

{
  "account_id": "...",
  "zone_id": "...",
  "zone_name": "example.com",
  "sites": [
    {
      "hostname": "app.example.com",
      "port": 8080,
      "tunnel_id": "...",
      "tunnel_name": "starchild-app-example-com",
      "run_token": "...",
      "app_cmd": "python3 server.py",
      "app_dir": "/data/workspace/projects/myapp"
    },
    {
      "hostname": "blog.example.com",
      "port": 3000,
      "tunnel_id": "...",
      "run_token": "...",
      "app_cmd": "",
      "app_dir": ""
    }
  ],
  "hostname": "blog.example.com",
  "port": 3000,
  "tunnel_id": "...",
  "run_token": "...",
  "app_cmd": "",
  "app_dir": ""
}

keepalive.sh は sites[] を読み取り、すべてのサイトを 1 回のパスで保護します — 1 つのウォッチドッグで、すべてのホスト名をカバーします。これは「各サイトがそれぞれ独自のトンネル + 独自の keepalive を持ち、1 つしか監視されていなかった」バグの修正です。現在は、設定されたすべてのサイトを認識する keepalive プロセスがちょうど 1 つだけ存在します。

複数サイト — 設計

1 つのトンネル、多数のホスト名、1 つのウォッチドッグ。 これが唯一まともな構成です:

  • setup.py はデフォルトで、アカウント上で最初に見つけた正常なトンネルを再利用します。新しいホスト名をトンネルの既存の ingress ルールにマージし(他のホスト名は保持されます)、DNS CNAME をそのトンネルに向けます。
  • .cf_state.json は sites[] 配列を保持します。setup.py を実行するたびに 1 つのエントリを追加(または置換)します。teardown.py は 1 つのエントリを削除します。
  • keepalive.sh は sites[] を反復処理し、すべてのサイトを保護します。1 つのプロセス、1 つのウォッチドッグ、すべてのホスト名。サイトが別のサイトとトンネルを共有している場合、同じ cloudflared プロセスが両方を処理します — keepalive は 2 つ目を起動しません。

エージェントがこれを間違える場合(このセクションを書くきっかけとなったバグ): サイトごとに新しいトンネルを作成すると、N 個の cloudflared プロセス、N 個の PID ファイル、N 個のウォッチドッグを配線することになり — 実際には 1 つのウォッチドッグしか設定されません。他のトンネルは静かに停止し、誰も何週間も気づきません。トンネルを再利用し、sites[] に追加し、1 つの keepalive にすべてを守らせてください。

コメント