Hosting
Fly.io
目標: 永続ストレージ、自動 HTTPS、Discord/チャンネルアクセスを備えた Fly.io マシン上で OpenClaw Gateway を実行する。
必要なもの
- flyctl CLI がインストール済み
- Fly.io アカウント(無料枠で可)
- モデル認証: 選択したモデルプロバイダーの API キー
- チャンネル認証情報: Discord bot token、Telegram token など
初心者向けクイック手順
- リポジトリをクローン →
fly.tomlをカスタマイズ - アプリ + ボリュームを作成 → シークレットを設定
fly deployでデプロイ- SSH で入って設定を作成、または Control UI を使用
Fly アプリを作成する
# Clone the repogit clone https://github.com/openclaw/openclaw.gitcd openclaw # Create a new Fly app (pick your own name)fly apps create my-openclaw # Create a persistent volume (1GB is usually enough)fly volumes create openclaw_data --size 1 --region iadヒント: 自分に近いリージョンを選択する。一般的な選択肢: lhr(ロンドン)、iad(バージニア)、sjc(サンノゼ)。
fly.toml を設定する
fly.toml を編集して、アプリ名と要件に合わせる。
セキュリティ上の注意: デフォルト設定では公開 URL が露出する。公開 IP のない強化済みデプロイについては、プライベートデプロイ を参照するか、deploy/fly.private.toml を使用する。
app = "my-openclaw" # Your app nameprimary_region = "iad" [build] dockerfile = "Dockerfile" [env] NODE_ENV = "production" OPENCLAW_PREFER_PNPM = "1" OPENCLAW_STATE_DIR = "/data" NODE_OPTIONS = "--max-old-space-size=1536" [processes] app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan" [http_service] internal_port = 3000 force_https = true auto_stop_machines = false auto_start_machines = true min_machines_running = 1 processes = ["app"] [[vm]] size = "shared-cpu-2x" memory = "2048mb" [mounts] source = "openclaw_data" destination = "/data"OpenClaw Docker イメージは tini をエントリポイントとして使用する。Fly のプロセスコマンドは Docker の ENTRYPOINT を置き換えずに CMD を置き換えるため、プロセスは引き続き 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" |
ボリューム上に状態を永続化する |
シークレットを設定する
# Required: Gateway token (for non-loopback binding)fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) # Model provider API keysfly secrets set ANTHROPIC_API_KEY=example-anthropic-key-not-real # Optional: Other providersfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # Channel tokensfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-token注記:
- 非 loopback バインド(
--bind lan)には、有効な Gateway 認証パスが必要。この Fly.io の例ではOPENCLAW_GATEWAY_TOKENを使用しているが、gateway.auth.passwordまたは正しく設定された非 loopback のtrusted-proxyデプロイでも要件を満たす。 - これらのトークンはパスワードと同様に扱う。
- すべての API キーとトークンには、設定ファイルより env vars を優先する。これにより、誤って露出またはログ出力される可能性がある
openclaw.jsonにシークレットを入れずに済む。
デプロイする
fly deploy初回デプロイでは Docker イメージをビルドする(約 2〜3 分)。以降のデプロイはより高速。
デプロイ後、確認する:
fly statusfly logs次のように表示されるはず:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)[discord] logged in to discord as xxx設定ファイルを作成する
マシンに SSH で入って、適切な設定を作成する:
fly ssh console設定ディレクトリとファイルを作成する:
mkdir -p /datacat > /data/openclaw.json << 'EOF'{ "agents": { "defaults": { "model": { "primary": "anthropic/claude-opus-4-6", "fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"] }, "maxConcurrent": 4 }, "list": [ { "id": "main", "default": true } ] }, "auth": { "profiles": { "anthropic:default": { "mode": "token", "provider": "anthropic" }, "openai:default": { "mode": "token", "provider": "openai" } } }, "bindings": [ { "agentId": "main", "match": { "channel": "discord" } } ], "channels": { "discord": { "enabled": true, "groupPolicy": "allowlist", "guilds": { "YOUR_GUILD_ID": { "channels": { "general": { "allow": true } }, "requireMention": false } } } }, "gateway": { "mode": "local", "bind": "auto", "controlUi": { "allowedOrigins": [ "https://my-openclaw.fly.dev", "http://localhost:3000", "http://127.0.0.1:3000" ] } }, "meta": {}}EOF注記: OPENCLAW_STATE_DIR=/data の場合、設定パスは /data/openclaw.json。
注記: https://my-openclaw.fly.dev を実際の Fly アプリの
origin に置き換える。Gateway の起動時には、ランタイムの
--bind と --port の値からローカル Control UI origin がシードされるため、
設定が存在する前でも初回起動を進められるが、Fly 経由のブラウザーアクセスには
gateway.controlUi.allowedOrigins に正確な HTTPS origin を列挙する必要がある。
注記: Discord トークンは次のどちらからでも取得できる:
- 環境変数:
DISCORD_BOT_TOKEN(シークレットには推奨) - 設定ファイル:
channels.discord.token
env var を使用する場合、設定にトークンを追加する必要はない。Gateway は DISCORD_BOT_TOKEN を自動的に読み取る。
適用するために再起動する:
exitfly machine restart <machine-id>Gateway にアクセスする
Control UI
ブラウザーで開く:
fly openまたは https://my-openclaw.fly.dev/ にアクセスする
設定済みの共有シークレットで認証する。このガイドでは
OPENCLAW_GATEWAY_TOKEN の Gateway トークンを使用している。パスワード認証に切り替えた場合は、
代わりにそのパスワードを使用する。
ログ
fly logs # Live logsfly logs --no-tail # Recent logsSSH コンソール
fly ssh consoleトラブルシューティング
「App is not listening on expected address」
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 / メモリの問題
コンテナが再起動し続ける、または kill される。兆候: SIGABRT、v8::internal::Runtime_AllocateInYoungGeneration、または無言の再起動。
修正: fly.toml でメモリを増やす:
[[vm]] memory = "2048mb"または既存のマシンを更新する:
fly machine update <machine-id> --vm-memory 2048 -y注記: 512MB は小さすぎる。1GB でも動作する場合はあるが、負荷が高い場合や詳細ログ出力時に OOM になる可能性がある。2GB を推奨。
Gateway ロックの問題
Gateway が「already running」エラーで起動を拒否する。
これは、コンテナが再起動しても PID ロックファイルがボリューム上に残っている場合に発生する。
修正: ロックファイルを削除する:
fly ssh console --command "rm -f /data/gateway.*.lock"fly machine restart <machine-id>ロックファイルは /data/gateway.*.lock にある(サブディレクトリ内ではない)。
設定が読み取られない
--allow-unconfigured は起動ガードをバイパスするだけ。/data/openclaw.json を作成または修復しないため、通常のローカル Gateway 起動を行いたい場合は、実際の設定が存在し、gateway.mode="local" が含まれていることを確認する。
設定が存在することを確認する:
fly ssh console --command "cat /data/openclaw.json"SSH 経由で設定を書き込む
fly ssh console -C コマンドはシェルのリダイレクトをサポートしない。設定ファイルを書き込むには:
# Use echo + tee (pipe from local to remote)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json" # Or use sftpfly sftp shell> put /local/path/config.json /data/openclaw.json注記: ファイルがすでに存在する場合、fly sftp は失敗することがある。先に削除する:
fly ssh console --command "rm /data/openclaw.json"状態が永続化されない
再起動後に認証プロファイル、チャンネル/プロバイダー状態、またはセッションが失われる場合、 状態ディレクトリがコンテナのファイルシステムに書き込まれている。
修正: fly.toml に OPENCLAW_STATE_DIR=/data が設定されていることを確認し、再デプロイする。
更新
# Pull latest changesgit pull # Redeployfly deploy # Check healthfly statusfly logsマシンコマンドの更新
完全な再デプロイなしで起動コマンドを変更する必要がある場合:
# Get machine IDfly machines list # Update commandfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y # Or with memory increasefly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y注記: fly deploy 後、マシンコマンドは fly.toml 内の内容にリセットされる可能性がある。手動変更を行った場合は、デプロイ後に再適用する。
プライベートデプロイ(強化済み)
デフォルトでは、Fly は公開 IP を割り当てるため、Gateway は https://your-app.fly.dev でアクセス可能になる。これは便利だが、デプロイがインターネットスキャナー(Shodan、Censys など)に発見されることを意味する。
公開露出なしの強化済みデプロイには、プライベートテンプレートを使用する。
プライベートデプロイを使う場合
- アウトバウンドの呼び出し/メッセージのみを行う(インバウンド Webhook なし)
- Webhook コールバックには ngrok または Tailscale トンネルを使用する
- ブラウザーではなく SSH、プロキシ、または WireGuard 経由で Gateway にアクセスする
- デプロイをインターネットスキャナーから隠したい
セットアップ
標準設定の代わりに deploy/fly.private.toml を使用する:
# Deploy with private configfly deploy -c deploy/fly.private.tomlまたは既存のデプロイを変換する:
# List current IPsfly ips list -a my-openclaw # Release public IPsfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw # Switch to private config so future deploys don't re-allocate public IPs# (remove [http_service] or deploy with the private template)fly deploy -c deploy/fly.private.toml # Allocate private-only IPv6fly ips allocate-v6 --private -a my-openclawこの後、fly ips list には private タイプの IP のみが表示されるはず:
VERSION IP TYPE REGIONv6 fdaa:x:x:x:x::x private globalプライベートデプロイへのアクセス
公開 URL がないため、次のいずれかの方法を使用する:
オプション 1: ローカルプロキシ(最も簡単)
# Forward local port 3000 to the appfly proxy 3000:3000 -a my-openclaw # Then open http://localhost:3000 in browserオプション 2: WireGuard VPN
# WireGuard 設定を作成(一度だけ)fly wireguard create # WireGuard クライアントにインポートし、内部 IPv6 経由でアクセス# 例: http://[fdaa:x:x:x:x::x]:3000オプション 3: SSH のみ
fly ssh console -a my-openclawプライベートデプロイでの Webhook
公開せずに Webhook コールバック(Twilio、Telnyx など)が必要な場合:
- ngrok トンネル - コンテナ内またはサイドカーとして ngrok を実行
- Tailscale Funnel - Tailscale 経由で特定のパスを公開
- アウトバウンドのみ - 一部のプロバイダー(Twilio)は Webhook なしでアウトバウンド通話に問題なく動作します
ngrok を使った音声通話設定の例:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}ngrok トンネルはコンテナ内で動作し、Fly アプリ自体を公開せずに公開 Webhook URL を提供します。転送されたホストヘッダーが受け入れられるように、webhookSecurity.allowedHosts を公開トンネルのホスト名に設定します。
セキュリティ上の利点
| 観点 | 公開 | プライベート |
|---|---|---|
| インターネットスキャナー | 検出可能 | 非表示 |
| 直接攻撃 | 可能 | ブロック |
| Control UI アクセス | ブラウザー | プロキシ/VPN |
| Webhook 配信 | 直接 | トンネル経由 |
メモ
- Fly.io は x86 アーキテクチャ を使用します(ARM ではありません)
- Dockerfile は両方のアーキテクチャに対応しています
- WhatsApp/Telegram のオンボーディングには、
fly ssh consoleを使用します - 永続データは
/dataのボリュームにあります - Signal には Java + signal-cli が必要です。カスタムイメージを使用し、メモリを 2GB 以上に保ってください。
コスト
推奨設定(shared-cpu-2x、2GB RAM)の場合:
- 使用量に応じて月額約 $10-15
- 無料枠には一定の許容量が含まれます
詳細は Fly.io pricing を参照してください。
次のステップ
- メッセージングチャネルを設定する: Channels
- Gateway を設定する: Gateway configuration
- OpenClaw を最新に保つ: Updating