メインコンテンツへスキップ

Fly.ioデプロイ

目標: Fly.ioのmachine上で、永続ストレージ、自動HTTPS、Discord/channelアクセスを備えたOpenClaw Gatewayを実行すること。

必要なもの

  • インストール済みのflyctl CLI
  • Fly.ioアカウント(free tierで可)
  • モデル認証: 使用するモデルプロバイダーのAPIキー
  • Channel認証情報: Discord botトークン、Telegramトークンなど

初心者向けクイックパス

  1. リポジトリをclone → fly.tomlをカスタマイズ
  2. app + volumeを作成 → secretsを設定
  3. fly deployでデプロイ
  4. SSHで入り設定を作成、またはControl UIを使用
1

Fly appを作成する

# リポジトリをclone
git clone https://github.com/openclaw/openclaw.git
cd openclaw

# 新しいFly appを作成(名前は自分のものにする)
fly apps create my-openclaw

# 永続volumeを作成(通常は1GBで十分)
fly volumes create openclaw_data --size 1 --region iad
Tip: 自分に近いリージョンを選んでください。一般的な選択肢: lhr(ロンドン)、iad(バージニア)、sjc(サンノゼ)。
2

fly.tomlを設定する

app名と要件に合わせてfly.tomlを編集します。セキュリティ注記: デフォルト設定ではpublic URLが公開されます。public IPなしの強化構成については、Private Deploymentを参照するか、fly.private.tomlを使用してください。
app = "my-openclaw"  # app名
primary_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"
主要設定:
設定理由
--bind lanFlyのproxyがgatewayに到達できるように0.0.0.0へbindする
--allow-unconfigured設定ファイルなしで起動する(後で作成する)
internal_port = 3000Flyのhealth check用に--port 3000(またはOPENCLAW_GATEWAY_PORT)と一致させる必要がある
memory = "2048mb"512MBでは不足。2GB推奨
OPENCLAW_STATE_DIR = "/data"volume上に状態を永続化する
3

secretsを設定する

# 必須: Gatewayトークン(非loopback bind用)
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)

# モデルプロバイダーAPIキー
fly secrets set ANTHROPIC_API_KEY=sk-ant-...

# 任意: その他のプロバイダー
fly secrets set OPENAI_API_KEY=sk-...
fly secrets set GOOGLE_API_KEY=...

# Channelトークン
fly secrets set DISCORD_BOT_TOKEN=MTQ...
注記:
  • 非loopback bind(--bind lan)には有効なgateway認証パスが必要です。このFly.io例ではOPENCLAW_GATEWAY_TOKENを使用していますが、gateway.auth.passwordや、正しく設定された非loopback trusted-proxyデプロイでも要件を満たせます。
  • これらのトークンはパスワードと同様に扱ってください。
  • すべてのAPIキーとトークンは、設定ファイルより環境変数を推奨します。これにより、シークレットがopenclaw.jsonに入って誤って露出したりログに残ったりするのを防げます。
4

デプロイする

fly deploy
初回デプロイではDockerイメージをビルドします(約2〜3分)。以後のデプロイはより高速です。デプロイ後に確認します:
fly status
fly logs
次のような表示が出るはずです:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
5

設定ファイルを作成する

properな設定を作成するため、machineにSSHで入ります:
fly ssh console
設定ディレクトリとファイルを作成します:
mkdir -p /data
cat > /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"
  },
  "meta": {}
}
EOF
注記: OPENCLAW_STATE_DIR=/dataの場合、設定パスは/data/openclaw.jsonです。注記: Discordトークンは次のいずれかから取得できます:
  • 環境変数: DISCORD_BOT_TOKEN(シークレットには推奨)
  • 設定ファイル: channels.discord.token
環境変数を使う場合、設定にトークンを追加する必要はありません。gatewayは自動的にDISCORD_BOT_TOKENを読み取ります。適用するため再起動します:
exit
fly machine restart <machine-id>
6

Gatewayにアクセスする

Control UI

ブラウザーで開きます:
fly open
またはhttps://my-openclaw.fly.dev/にアクセスします。設定された共有シークレットで認証してください。このガイドでは OPENCLAW_GATEWAY_TOKENのgatewayトークンを使用しています。パスワード認証に切り替えた場合は、そのパスワードを使用してください。

ログ

fly logs              # ライブログ
fly logs --no-tail    # 最近のログ

SSHコンソール

fly ssh console

トラブルシューティング

「App is not listening on expected address」

gatewayが0.0.0.0ではなく127.0.0.1にbindしています。 修正: fly.tomlのprocess commandに--bind lanを追加してください。

Health checks failing / connection refused

Flyが設定ポート上のgatewayに到達できていません。 修正: internal_portがgatewayポートと一致していることを確認してください(--port 3000またはOPENCLAW_GATEWAY_PORT=3000を設定)。

OOM / メモリ問題

コンテナが再起動し続ける、またはkillされます。兆候: SIGABRTv8::internal::Runtime_AllocateInYoungGeneration、または無言の再起動。 修正: fly.tomlでメモリを増やしてください:
[[vm]]
  memory = "2048mb"
または既存machineを更新します:
fly machine update <machine-id> --vm-memory 2048 -y
注記: 512MBでは不足です。1GBでも動くことはありますが、高負荷時や詳細ログ有効時にはOOMになる可能性があります。2GBを推奨します。

Gateway Lock問題

Gatewayが「already running」エラーで起動を拒否します。 これは、コンテナ再起動後もPID lockファイルがvolume上に残っているときに発生します。 修正: lockファイルを削除してください:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
lockファイルは/data/gateway.*.lockにあります(サブディレクトリ内ではありません)。

設定が読み込まれていない

--allow-unconfiguredは起動時ガードを回避するだけです。/data/openclaw.jsonを作成したり修復したりはしないため、実際の設定が存在し、通常のlocal gateway起動をしたい場合はgateway.mode="local"が含まれていることを確認してください。 設定が存在することを確認します:
fly ssh console --command "cat /data/openclaw.json"

SSH経由で設定を書き込む

fly ssh console -Cコマンドはシェルのリダイレクトをサポートしません。設定ファイルを書き込むには:
# echo + teeを使用(ローカルからリモートへパイプ)
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"

# またはsftpを使用
fly sftp shell
> put /local/path/config.json /data/openclaw.json
注記: ファイルがすでに存在する場合、fly sftpは失敗することがあります。先に削除してください:
fly ssh console --command "rm /data/openclaw.json"

状態が永続化されない

再起動後に認証プロファイル、channel/provider状態、またはセッションが失われる場合、 state dirがコンテナファイルシステムに書き込まれています。 修正: fly.tomlOPENCLAW_STATE_DIR=/dataが設定されていることを確認し、再デプロイしてください。

更新

# 最新変更を取得
git pull

# 再デプロイ
fly deploy

# 正常性を確認
fly status
fly logs

Machineコマンドの更新

完全な再デプロイなしで起動コマンドを変更したい場合:
# machine IDを取得
fly machines list

# コマンドを更新
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y

# またはメモリ増加付き
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
注記: fly deploy後、machine commandはfly.tomlの内容にリセットされる場合があります。手動変更を加えた場合は、デプロイ後に再適用してください。

Private Deployment(強化構成)

デフォルトでは、Flyはpublic IPを割り当てるため、gatewayはhttps://your-app.fly.devでアクセス可能になります。これは便利ですが、インターネットスキャナー(Shodan、Censysなど)から発見可能であることを意味します。 公開露出なしの強化構成にするには、privateテンプレートを使用してください。

private deploymentを使うべき場面

  • アウトバウンドの呼び出し/メッセージのみを行う(受信Webhookなし)
  • WebhookコールバックにはngrokまたはTailscaleトンネルを使用する
  • gatewayへはブラウザーではなく、SSH、proxy、またはWireGuard経由でアクセスする
  • デプロイをインターネットスキャナーから隠したい

セットアップ

標準設定の代わりにfly.private.tomlを使用します:
# private設定でデプロイ
fly deploy -c fly.private.toml
または既存デプロイを変換します:
# 現在のIPを一覧表示
fly ips list -a my-openclaw

# public IPを解放
fly ips release <public-ipv4> -a my-openclaw
fly ips release <public-ipv6> -a my-openclaw

# 今後のデプロイでpublic IPが再割り当てされないようprivate設定へ切り替え
# ([http_service]を削除するか、privateテンプレートでデプロイ)
fly deploy -c fly.private.toml

# private専用IPv6を割り当て
fly ips allocate-v6 --private -a my-openclaw
この後、fly ips listにはprivate型のIPのみが表示されるはずです:
VERSION  IP                   TYPE             REGION
v6       fdaa:x:x:x:x::x      private          global

private deploymentへのアクセス

public URLがないため、次のいずれかの方法を使用します: オプション1: ローカルproxy(最も簡単)
# ローカルの3000番ポートをappへ転送
fly proxy 3000:3000 -a my-openclaw

# その後、ブラウザーでhttp://localhost:3000を開く
オプション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

private deploymentでのWebhook

公開露出なしでWebhookコールバック(Twilio、Telnyxなど)が必要な場合:
  1. ngrokトンネル - ngrokをコンテナ内またはsidecarとして実行する
  2. Tailscale Funnel - 特定パスをTailscale経由で公開する
  3. アウトバウンド専用 - 一部のプロバイダー(Twilio)はWebhookなしでもアウトバウンド通話が問題なく動作する
ngrokを使ったvoice-call設定例:
{
  plugins: {
    entries: {
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio",
          tunnel: { provider: "ngrok" },
          webhookSecurity: {
            allowedHosts: ["example.ngrok.app"],
          },
        },
      },
    },
  },
}
ngrokトンネルはコンテナ内で実行され、Fly app自体を公開せずにpublicなWebhook URLを提供します。転送されたhostヘッダーを受け入れられるように、公開トンネルのホスト名をwebhookSecurity.allowedHostsに設定してください。

セキュリティ上の利点

項目PublicPrivate
インターネットスキャナー発見可能隠蔽
直接攻撃可能ブロック
Control UIアクセスブラウザーProxy/VPN
Webhook配信直接トンネル経由

注記

  • Fly.ioはx86アーキテクチャを使用します(ARMではありません)
  • Dockerfileは両方のアーキテクチャと互換性があります
  • WhatsApp/Telegramオンボーディングにはfly ssh consoleを使用してください
  • 永続データは/dataのvolume上に保存されます
  • SignalにはJava + signal-cliが必要です。カスタムイメージを使い、メモリは2GB以上を維持してください。

コスト

推奨構成(shared-cpu-2x、2GB RAM)では:
  • 使用量に応じておよそ$10〜15/月
  • free tierに一定の枠が含まれます
詳細はFly.io pricingを参照してください。

次のステップ