Hosting

Fly.io

Ziel: OpenClaw Gateway auf einer Fly.io-Maschine mit persistentem Speicher, automatischem HTTPS und Zugriff über Discord/Kanäle ausführen.

Voraussetzungen

  • flyctl CLI installiert
  • Fly.io-Konto (kostenloses Kontingent ist ausreichend)
  • Modellauthentifizierung: API-Schlüssel für Ihren gewählten Modell-Provider
  • Kanal-Anmeldedaten: Discord-Bot-Token, Telegram-Token usw.

Schnelleinstieg für Einsteiger

  1. Repository klonen, fly.toml anpassen
  2. App und Volume erstellen, Secrets festlegen
  3. Mit fly deploy bereitstellen
  4. Per SSH eine Konfiguration erstellen oder die Control UI verwenden
  • Fly-App erstellen

    bash
    git clone https://github.com/openclaw/openclaw.gitcd openclaw # wählen Sie einen eigenen Namenfly apps create my-openclaw # 1 GB ist normalerweise ausreichendfly volumes create openclaw_data --size 1 --region iad

    Wählen Sie eine Region in Ihrer Nähe. Häufig verwendete Optionen: lhr (London), iad (Virginia), sjc (San Jose).

  • fly.toml konfigurieren

    Bearbeiten Sie fly.toml entsprechend Ihrem App-Namen und Ihren Anforderungen. Die im Repository nachverfolgte Datei fly.toml ist die unten gezeigte öffentliche Vorlage; deploy/fly.private.toml ist die gehärtete Variante ohne öffentliche IP-Adresse (siehe Private Bereitstellung).

    toml
    app = "my-openclaw"  # Ihr 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"

    Der Einstiegspunkt des OpenClaw-Docker-Images ist tini, das standardmäßig node openclaw.mjs gateway ausführt. Fly [processes] ersetzt den Docker-Befehl CMD (hier wird node dist/index.js gateway ... direkt ausgeführt, also derselbe kompilierte Einstiegspunkt), ohne ENTRYPOINT zu verändern, sodass der Prozess weiterhin unter tini ausgeführt wird.

    Wichtige Einstellungen:

    Einstellung Grund
    --bind lan Bindet an 0.0.0.0, damit der Proxy von Fly den Gateway erreichen kann
    --allow-unconfigured Startet ohne Konfigurationsdatei (Sie erstellen anschließend eine)
    internal_port = 3000 Muss für die Zustandsprüfungen von Fly mit --port 3000 (oder OPENCLAW_GATEWAY_PORT) übereinstimmen
    memory = "2048mb" 512 MB sind zu wenig; 2 GB werden empfohlen
    OPENCLAW_STATE_DIR = "/data" Speichert den Zustand dauerhaft auf dem Volume
  • Secrets festlegen

    bash
    # erforderlich: Gateway-Authentifizierungstoken für Bindings außerhalb von Loopbackfly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) # API-Schlüssel für Modell-Providerfly secrets set ANTHROPIC_API_KEY=example-anthropic-key-not-real # optional: weitere Providerfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # Kanal-Tokenfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-token

    Bindings außerhalb von Loopback (--bind lan) erfordern einen gültigen Gateway-Authentifizierungspfad. Dieses Beispiel verwendet OPENCLAW_GATEWAY_TOKEN, aber gateway.auth.password oder eine korrekt konfigurierte vertrauenswürdige Proxy-Bereitstellung außerhalb von Loopback erfüllen die Anforderung ebenfalls. Informationen zum SecretRef-Vertrag finden Sie unter Secret-Verwaltung.

    Behandeln Sie diese Token wie Passwörter. Bevorzugen Sie für API-Schlüssel und Token Umgebungsvariablen/fly secrets gegenüber der Konfigurationsdatei, damit Secrets nicht in openclaw.json gespeichert werden.

  • Bereitstellen

    bash
    fly deploy

    Bei der ersten Bereitstellung wird das Docker-Image erstellt. Überprüfen Sie anschließend die Bereitstellung:

    bash
    fly statusfly logs

    Beim Start protokolliert der Gateway gateway ready, sobald der HTTP-/WebSocket-Listener bereit ist. Die eigene Zustandsprüfung von Fly überwacht gemäß fly.toml den Wert internal_port = 3000. Die Docker-Anweisung HEALTHCHECK des Images fragt zusätzlich /healthz auf dem Standardport 18789 ab; diese Prüfung wird hier nicht verwendet, da diese Bereitstellung den Gateway mit --port 3000 überschreibt.

  • Konfigurationsdatei erstellen

    Stellen Sie per SSH eine Verbindung zur Maschine her, um eine ordnungsgemäße Konfiguration zu erstellen:

    bash
    fly ssh console
    bash
    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

    Mit OPENCLAW_STATE_DIR=/data lautet der Konfigurationspfad /data/openclaw.json.

    Ersetzen Sie https://my-openclaw.fly.dev durch den tatsächlichen Origin Ihrer Fly-App. Beim Start fügt der Gateway lokale Control-UI-Origins anhand der Laufzeitwerte --bind und --port hinzu, damit der erste Start erfolgen kann, bevor eine Konfiguration vorhanden ist. Für den Browserzugriff über Fly muss der genaue HTTPS-Origin dennoch unter gateway.controlUi.allowedOrigins aufgeführt sein.

    Das Discord-Token kann aus einer der folgenden Quellen stammen:

    • Umgebungsvariable DISCORD_BOT_TOKEN (für Secrets empfohlen); sie muss nicht zur Konfiguration hinzugefügt werden, da der Gateway sie automatisch liest
    • Konfigurationsdatei channels.discord.token

    Starten Sie neu, um die Änderungen anzuwenden:

    bash
    exitfly machine restart <machine-id>
  • Auf den Gateway zugreifen

    Control UI

    bash
    fly open

    Oder rufen Sie https://my-openclaw.fly.dev/ auf.

    Authentifizieren Sie sich mit dem konfigurierten gemeinsamen Secret: dem Gateway-Token aus OPENCLAW_GATEWAY_TOKEN oder Ihrem Passwort, falls Sie zur Passwortauthentifizierung gewechselt haben.

    Protokolle

    bash
    fly logs              # Live-Protokollefly logs --no-tail    # aktuelle Protokolle

    SSH-Konsole

    bash
    fly ssh console
  • Fehlerbehebung

    „App lauscht nicht an der erwarteten Adresse“

    Der Gateway bindet an 127.0.0.1 statt an 0.0.0.0.

    Behebung: Fügen Sie dem Prozessbefehl in fly.toml die Option --bind lan hinzu.

    Zustandsprüfungen schlagen fehl / Verbindung abgelehnt

    Fly kann den Gateway am konfigurierten Port nicht erreichen.

    Behebung: Stellen Sie sicher, dass internal_port mit dem Gateway-Port (--port 3000 oder OPENCLAW_GATEWAY_PORT=3000) übereinstimmt.

    OOM-/Speicherprobleme

    Der Container wird ständig neu gestartet oder beendet. Anzeichen: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration oder Neustarts ohne Fehlermeldung.

    Behebung: Erhöhen Sie den Speicher in fly.toml:

    toml
    [[vm]]  memory = "2048mb"

    Oder aktualisieren Sie eine vorhandene Maschine:

    bash
    fly machine update <machine-id> --vm-memory 2048 -y

    512 MB sind zu wenig. 1 GB kann ausreichen, aber unter Last oder bei ausführlicher Protokollierung kann es zu einem OOM-Fehler kommen. 2 GB werden empfohlen.

    Probleme mit der Gateway-Sperre

    Der Gateway verweigert nach einem Container-Neustart den Start mit Fehlermeldungen, laut denen er „bereits ausgeführt“ wird.

    Die Sperrdatei für die Einzelinstanz befindet sich unter <tmpdir>/openclaw-<uid>/gateway.<hash>.lock (Linux: /tmp/openclaw-<uid>/gateway.<hash>.lock) und nicht auf dem persistenten Volume /data. Ein vollständiger Container-Neustart löscht sie daher normalerweise zusammen mit dem übrigen Container-Dateisystem. Falls die Sperre erhalten bleibt (beispielsweise bei einem fly machine restart, der das Container-Dateisystem beibehält) und den Start blockiert, entfernen Sie sie manuell:

    bash
    fly ssh console --command "rm -f /tmp/openclaw-*/gateway.*.lock"fly machine restart <machine-id>

    Konfiguration wird nicht gelesen

    --allow-unconfigured umgeht lediglich die Startsperre. Die Option erstellt oder repariert /data/openclaw.json nicht. Stellen Sie daher sicher, dass Ihre tatsächliche Konfiguration vorhanden ist und für einen normalen lokalen Gateway-Start "gateway": { "mode": "local" } enthält.

    Überprüfen Sie, ob die Konfiguration vorhanden ist:

    bash
    fly ssh console --command "cat /data/openclaw.json"

    Konfiguration per SSH schreiben

    fly ssh console -C unterstützt keine Shell-Umleitung. So schreiben Sie eine Konfigurationsdatei:

    bash
    # echo + tee (Pipe von lokal nach remote)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json" # oder SFTPfly sftp shell> put /local/path/config.json /data/openclaw.json

    fly sftp kann fehlschlagen, wenn die Datei bereits vorhanden ist; löschen Sie sie zuerst:

    bash
    fly ssh console --command "rm /data/openclaw.json"

    Zustand wird nicht dauerhaft gespeichert

    Wenn Authentifizierungsprofile, Kanal-/Provider-Zustand oder Sitzungen nach einem Neustart verloren gehen, wird das Zustandsverzeichnis in das Container-Dateisystem statt auf das Volume geschrieben.

    Behebung: Stellen Sie sicher, dass OPENCLAW_STATE_DIR=/data in fly.toml festgelegt ist, und stellen Sie die App erneut bereit.

    Aktualisieren

    bash
    git pullfly deployfly statusfly logs

    git pull + fly deploy ist hier der überwachte Aktualisierungspfad: Dabei wird das Image aus dem Dockerfile neu erstellt, sodass die CLI-/Gateway-Version, das Basis-Betriebssystem-Image und sämtliche Änderungen am Dockerfile gemeinsam aktualisiert werden. openclaw update im laufenden Container ist nicht derselbe Vorgang, da das Image als per Docker erstellter dist/-Verzeichnisbaum ohne .git-Checkout und ohne von npm verwaltete globale Installation ausgeliefert wird, die der Befehl erkennen könnte. Informationen zu diesem Ablauf bei VM-ähnlichen Installationen finden Sie unter Aktualisieren.

    Maschinenbefehl aktualisieren

    So ändern Sie den Startbefehl ohne vollständige erneute Bereitstellung:

    bash
    fly machines listfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y # oder mit einer Speichererhöhungfly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y

    Ein späteres fly deploy setzt den Maschinenbefehl auf den in fly.toml angegebenen Wert zurück. Wenden Sie manuelle Änderungen nach der erneuten Bereitstellung erneut an.

    Private Bereitstellung (gehärtet)

    Standardmäßig weist Fly öffentliche IP-Adressen zu. Dadurch ist Ihr Gateway unter https://your-app.fly.dev erreichbar und kann von Internet-Scannern (Shodan, Censys usw.) gefunden werden.

    Verwenden Sie deploy/fly.private.toml für eine gehärtete Bereitstellung ohne öffentliche IP-Adresse: Die Datei enthält keinen Abschnitt [http_service], sodass kein öffentlicher eingehender Zugriff zugewiesen wird.

    Wann eine private Bereitstellung sinnvoll ist

    • Nur ausgehende Aufrufe/Nachrichten (keine eingehenden Webhooks)
    • ngrok- oder Tailscale-Tunnel verarbeiten sämtliche Webhook-Rückrufe
    • Der Zugriff auf den Gateway erfolgt per SSH, Proxy oder WireGuard statt über einen Browser
    • Die Bereitstellung soll vor Internet-Scannern verborgen bleiben

    Einrichtung

    bash
    fly deploy -c deploy/fly.private.toml

    Oder konvertieren Sie eine vorhandene Bereitstellung:

    bash
    # aktuelle IP-Adressen auflistenfly ips list -a my-openclaw # öffentliche IP-Adressen freigebenfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw # zur privaten Konfiguration wechseln, damit künftige Bereitstellungen keine öffentlichen IP-Adressen erneut zuweisenfly deploy -c deploy/fly.private.toml # ausschließlich private IPv6-Adresse zuweisenfly ips allocate-v6 --private -a my-openclaw

    Danach sollte fly ips list nur eine IP vom Typ private anzeigen:

    text
    VERSION  IP                   TYPE             REGIONv6       fdaa:x:x:x:x::x      private          global

    Zugriff auf eine private Bereitstellung

    Option 1: Lokaler Proxy (am einfachsten)

    bash
    fly proxy 3000:3000 -a my-openclaw# http://localhost:3000 in einem Browser öffnen

    Option 2: WireGuard-VPN

    bash
    fly wireguard create# in einen WireGuard-Client importieren und dann über die interne IPv6-Adresse zugreifen# Beispiel: http://[fdaa:x:x:x:x::x]:3000

    Option 3: Nur SSH

    bash
    fly ssh console -a my-openclaw

    Webhooks bei einer privaten Bereitstellung

    Für Webhook-Rückrufe (Twilio, Telnyx usw.) ohne öffentliche Erreichbarkeit:

    1. ngrok-Tunnel: ngrok im Container oder als Sidecar ausführen
    2. Tailscale Funnel: bestimmte Pfade über Tailscale verfügbar machen
    3. Nur ausgehend: Einige Provider (Twilio) funktionieren für ausgehende Anrufe ohne Webhooks

    Beispielkonfiguration für Sprachanrufe mit ngrok unter plugins.entries.voice-call.config:

    json5
    {  plugins: {    entries: {      "voice-call": {        enabled: true,        config: {          provider: "twilio",          tunnel: { provider: "ngrok" },          webhookSecurity: {            allowedHosts: ["example.ngrok.app"],          },        },      },    },  },}

    Der ngrok-Tunnel wird innerhalb des Containers ausgeführt und stellt eine öffentliche Webhook-URL bereit, ohne die Fly-App selbst öffentlich zugänglich zu machen. Setzen Sie webhookSecurity.allowedHosts auf den Hostnamen des Tunnels, damit weitergeleitete Host-Header akzeptiert werden.

    Sicherheitsabwägungen

    Aspekt Öffentlich Privat
    Internet-Scanner Auffindbar Verborgen
    Direkte Angriffe Möglich Blockiert
    Zugriff auf die Bedienoberfläche Browser Proxy/VPN
    Webhook-Zustellung Direkt Über Tunnel

    Hinweise

    • Fly.io verwendet die x86-Architektur; das Dockerfile ist sowohl mit x86 als auch mit ARM kompatibel.
    • Verwenden Sie für das Onboarding von WhatsApp/Telegram fly ssh console.
    • Persistente Daten befinden sich auf dem Volume unter /data.
    • Signal benötigt signal-cli (eine Java-basierte CLI) im Image; verwenden Sie ein benutzerdefiniertes Image und mindestens 2 GB Arbeitsspeicher.

    Kosten

    Mit der empfohlenen Konfiguration (shared-cpu-2x, 2 GB RAM) können Sie abhängig von der Nutzung mit etwa 10–15 USD pro Monat rechnen; der kostenlose Tarif deckt ein gewisses Basiskontingent ab. Die aktuellen Preise finden Sie unter Fly.io-Preise.

    Nächste Schritte

    Verwandte Themen

    Was this useful?
    On this page

    On this page