このページの内容
このページの内容
Hosting
Fly.io
目標: 永続ストレージ、自動 HTTPS、Discord/チャンネルアクセスを備えた Fly.io マシン上で OpenClaw Gateway を実行します。
必要なもの
- flyctl CLI がインストール済み
- Fly.io アカウント(無料枠で利用可能)
- モデル認証: 選択したモデルプロバイダーの API キー
- チャンネル認証情報: Discord ボットトークン、Telegram トークンなど
初心者向けクイック手順
- リポジトリをクローンし、
fly.tomlをカスタマイズ - アプリとボリュームを作成し、シークレットを設定
fly deployでデプロイ- SSH で接続して設定を作成するか、Control UI を使用
Fly アプリを作成
近くのリージョンを選択してください。一般的な選択肢: lhr(ロンドン)、iad(バージニア)、sjc(サンノゼ)。
fly.toml を設定
アプリ名と要件に合わせて fly.toml を編集します。リポジトリで追跡されている fly.toml は、以下に示す公開テンプレートです。deploy/fly.private.toml は、公開 IP を使用しない堅牢化されたバリアントです(プライベートデプロイを参照)。
OpenClaw Docker イメージのエントリーポイントは tini で、デフォルトでは node openclaw.mjs gateway を実行します。Fly の [processes] は、ENTRYPOINT を変更せずに Docker の CMD を置き換えます(ここでは、同じコンパイル済みエントリーポイントである node dist/index.js gateway ... を直接実行します)。そのため、プロセスは引き続き tini の下で実行されます。
主要設定:
| 設定 | 理由 |
|---|---|
--bind lan |
Fly のプロキシが Gateway に到達できるよう、0.0.0.0 にバインドします |
--allow-unconfigured |
設定ファイルなしで起動します(後で作成します) |
internal_port = 3000 |
Fly のヘルスチェックのため、--port 3000(または OPENCLAW_GATEWAY_PORT)と一致させる必要があります |
memory = "2048mb" |
512MB では小さすぎるため、2GB を推奨します |
OPENCLAW_STATE_DIR = "/data" |
ボリューム上に状態を永続化します |
シークレットを設定
非ループバックバインド(--bind lan)には、有効な Gateway 認証パスが必要です。この例では OPENCLAW_GATEWAY_TOKEN を使用しますが、gateway.auth.password または正しく設定された非ループバックの信頼済みプロキシデプロイでも要件を満たします。SecretRef の契約については、シークレット管理を参照してください。
これらのトークンはパスワードと同様に扱ってください。シークレットを openclaw.json に保存しないようにするため、API キーとトークンには設定ファイルよりも環境変数/fly secrets を使用することを推奨します。
デプロイ
最初のデプロイでは Docker イメージがビルドされます。デプロイ後に確認します。
HTTP/WebSocket リスナーが起動すると、Gateway の起動ログに gateway ready が記録されます。Fly 自体のヘルスチェックは、fly.toml に従って internal_port = 3000 を監視します。また、イメージの Docker HEALTHCHECK ディレクティブは、デフォルトポート 18789 上の /healthz もポーリングしますが、このデプロイでは Gateway を --port 3000 に上書きしているため使用されません。
設定ファイルを作成
マシンに SSH 接続し、適切な設定を作成します。
OPENCLAW_STATE_DIR=/data を使用する場合、設定パスは /data/openclaw.json です。
https://my-openclaw.fly.dev を実際の Fly アプリのオリジンに置き換えてください。Gateway の起動時には、ランタイムの --bind と --port の値からローカル Control UI のオリジンが初期設定されるため、設定が存在しない初回起動でも処理を続行できます。ただし、Fly 経由でブラウザからアクセスするには、gateway.controlUi.allowedOrigins に正確な HTTPS オリジンを指定する必要があります。
Discord トークンは、次のいずれかから取得できます。
- 環境変数
DISCORD_BOT_TOKEN(シークレットには推奨)。設定に追加する必要はなく、Gateway が自動的に読み取ります - 設定ファイル
channels.discord.token
適用するために再起動します。
Gateway にアクセス
Control UI
または、https://my-openclaw.fly.dev/ にアクセスします。
設定済みの共有シークレットで認証します。OPENCLAW_GATEWAY_TOKEN の Gateway トークン、またはパスワード認証に切り替えた場合はパスワードを使用します。
ログ
SSH コンソール
トラブルシューティング
「アプリが想定されたアドレスでリッスンしていない」
Gateway が 0.0.0.0 ではなく 127.0.0.1 にバインドされています。
修正: fly.toml のプロセスコマンドに --bind lan を追加します。
ヘルスチェックの失敗 / 接続拒否
Fly が設定済みポート上の Gateway に到達できません。
修正: internal_port が Gateway のポート(--port 3000 または OPENCLAW_GATEWAY_PORT=3000)と一致していることを確認します。
OOM / メモリの問題
コンテナが再起動を繰り返すか、強制終了されています。兆候: SIGABRT、v8::internal::Runtime_AllocateInYoungGeneration、または通知なしの再起動。
修正: fly.toml でメモリを増やします。
または、既存のマシンを更新します。
512MB では小さすぎます。1GB でも動作する場合がありますが、負荷が高い場合や詳細ログを有効にした場合は OOM が発生する可能性があります。2GB を推奨します。
Gateway ロックの問題
コンテナの再起動後、Gateway が「すでに実行中」というエラーで起動を拒否します。
ランタイムロックファイルは、永続 /data ボリューム上ではなく、<tmpdir>/openclaw-<uid>/gateway.<hash>.lock
および gateway.state.<hash>.lock(Linux:
/tmp/openclaw-<uid>/gateway.*.lock)に存在するため、通常はコンテナを完全に再起動すると、コンテナファイルシステムの他の部分とともに削除されます。ロックが残り(たとえば、コンテナファイルシステムを保持する fly machine restart の場合)起動を妨げる場合は、手動で削除します。
設定が読み取られない
--allow-unconfigured は起動ガードを回避するだけです。/data/openclaw.json を作成または修復することはないため、実際の設定が存在し、通常のローカル Gateway 起動に必要な "gateway": { "mode": "local" } が含まれていることを確認してください。
設定が存在することを確認します。
SSH 経由で設定を書き込む
fly ssh console -C はシェルのリダイレクトをサポートしていません。設定ファイルを書き込むには、次の手順を使用します。
ファイルがすでに存在する場合、fly sftp が失敗することがあります。先に削除してください。
状態が永続化されない
再起動後に認証プロファイル、チャンネル/プロバイダーの状態、またはセッションが失われる場合、状態ディレクトリがボリュームではなくコンテナファイルシステムに書き込まれています。
修正: fly.toml に OPENCLAW_STATE_DIR=/data が設定されていることを確認し、再デプロイします。
更新
ここでは、git pull + fly deploy が管理された手順です。Dockerfile からイメージを再ビルドするため、CLI/Gateway のバージョン、ベース OS イメージ、Dockerfile の変更がすべて同時に更新されます。実行中のコンテナ内での openclaw update は同じ操作ではありません。これは、イメージが Docker でビルドされた dist/ ツリーとして提供され、検出対象となる .git チェックアウトも npm 管理のグローバルインストールも含まれていないためです。VM 形式のインストールでの手順については、更新を参照してください。
マシンコマンドの更新
完全な再デプロイを行わずに起動コマンドを変更するには、次の手順を使用します。
後で fly deploy を実行すると、マシンコマンドは fly.toml に記載された内容に戻ります。再デプロイ後に手動変更を再適用してください。
プライベートデプロイ(堅牢化)
デフォルトでは、Fly は公開 IP を割り当てるため、Gateway は https://your-app.fly.dev でアクセス可能となり、インターネットスキャナー(Shodan、Censys など)から検出されます。
公開 IP なしで堅牢化したデプロイを行うには、deploy/fly.private.toml を使用します。これには [http_service] が含まれていないため、公開イングレスは割り当てられません。
プライベートデプロイを使用する場合
- 送信呼び出し/メッセージのみ(受信 Webhook なし)
- Webhook コールバックは ngrok または Tailscale トンネルで処理
- Gateway へのアクセスにはブラウザではなく SSH、プロキシ、または WireGuard を使用
- インターネットスキャナーからデプロイを隠す必要がある場合
セットアップ
または、既存のデプロイを変換します。
この後、fly ips list には private タイプの IP のみが表示されます。
プライベートデプロイへのアクセス
オプション 1:ローカルプロキシ(最も簡単)
オプション 2:WireGuard VPN
オプション 3:SSH のみ
プライベートデプロイでの Webhook
パブリックに公開せずに Webhook コールバック(Twilio、Telnyx など)を使用するには、次の方法があります。
- ngrok トンネル:コンテナ内またはサイドカーとして ngrok を実行
- Tailscale Funnel:Tailscale 経由で特定のパスを公開
- アウトバウンドのみ:一部のプロバイダー(Twilio)は、Webhook なしでアウトバウンド通話に対応
plugins.entries.voice-call.config 配下での ngrok を使用した音声通話設定の例:
ngrok トンネルはコンテナ内で実行され、Fly アプリ自体を公開することなくパブリック Webhook URL を提供します。転送されたホストヘッダーが受け入れられるよう、webhookSecurity.allowedHosts をトンネルのホスト名に設定します。
セキュリティ上のトレードオフ
| 項目 | パブリック | プライベート |
|---|---|---|
| インターネットスキャナー | 検出可能 | 非表示 |
| 直接攻撃 | 可能 | ブロック |
| Control UI へのアクセス | ブラウザー | プロキシ/VPN |
| Webhook の配信 | 直接 | トンネル経由 |
注意事項
- Fly.io は x86 アーキテクチャを使用します。この Dockerfile は x86 と ARM の両方に対応しています。
- WhatsApp/Telegram のオンボーディングには、
fly ssh consoleを使用します。 - 永続データは
/dataのボリュームに保存されます。 - Signal では、イメージに signal-cli(Java ベースの CLI)が必要です。カスタムイメージを使用し、メモリを 2GB 以上に維持してください。
コスト
推奨設定(shared-cpu-2x、2GB RAM)では、使用量に応じて月額約 $10~15 を見込んでください。無料利用枠で基本使用量の一部をまかなえます。現在の料金については、Fly.io の料金を参照してください。
次のステップ
- メッセージングチャンネルを設定:チャンネル
- Gateway を設定:Gateway の設定
- OpenClaw を最新の状態に維持:更新