Fly.io Deployment
Doel: OpenClaw Gateway draaien op een Fly.io-machine met persistente opslag, automatische HTTPS en Discord/kanaal-toegang.
Wat je nodig hebt
- flyctl CLI geïnstalleerd
- Fly.io-account (gratis tier werkt)
- Model-auth: API-key voor je gekozen model-provider
- Kanaalgegevens: Discord bot-token, Telegram-token, etc.
Snel starten voor beginners
- Kloon de repo → pas
fly.tomlaan - Maak app + volume → stel secrets in
- Deploy met
fly deploy - SSH erin om configuratie aan te maken of gebruik de Control UI
1) De Fly-app aanmaken
# Kloon de repo
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Maak een nieuwe Fly-app aan (kies je eigen naam)
fly apps create my-openclaw
# Maak een persistent volume aan (1GB is meestal voldoende)
fly volumes create openclaw_data --size 1 --region iad
Tip: Kies een regio dicht bij jou. Veelgebruikte opties: lhr (Londen), iad (Virginia), sjc (San Jose).
2) fly.toml configureren
Bewerk fly.toml zodat deze overeenkomt met je app-naam en vereisten.
Beveiligingsopmerking: De standaardconfiguratie stelt een publieke URL beschikbaar. Voor een geharde deployment zonder publiek IP, zie Privaat deployen of gebruik fly.private.toml.
app = "my-openclaw" # Je app-naam
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"
Belangrijke instellingen:
| Instelling | Waarom |
|---|---|
--bind lan | Bindt aan 0.0.0.0 zodat Fly’s proxy de gateway kan bereiken |
--allow-unconfigured | Start zonder configuratiebestand (je maakt er later een aan) |
internal_port = 3000 | Moet overeenkomen met --port 3000 (of OPENCLAW_GATEWAY_PORT) voor Fly health checks |
memory = "2048mb" | 512MB is te weinig; 2GB aanbevolen |
OPENCLAW_STATE_DIR = "/data" | Bewaart state op het volume |
3) Secrets instellen
# Vereist: Gateway-token (voor niet-loopback binding)
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
# API-keys voor model-providers
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
# Optioneel: andere providers
fly secrets set OPENAI_API_KEY=sk-...
fly secrets set GOOGLE_API_KEY=...
# Kanaal-tokens
fly secrets set DISCORD_BOT_TOKEN=MTQ...
Opmerkingen:
- Niet-loopback binds (
--bind lan) vereisenOPENCLAW_GATEWAY_TOKENvoor beveiliging. - Behandel deze tokens als wachtwoorden.
- Gebruik bij voorkeur omgevingsvariabelen in plaats van het configuratiebestand voor alle API-keys en tokens. Zo blijven geheimen buiten
openclaw.jsonwaar ze per ongeluk blootgesteld of gelogd kunnen worden.
4) Deployen
fly deploy
De eerste deploy bouwt de Docker-image (~2-3 minuten). Volgende deploys zijn sneller.
Na deployment verifiëren:
fly status
fly logs
Je zou moeten zien:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
5) Configuratiebestand aanmaken
SSH naar de machine om een goede configuratie aan te maken:
fly ssh console
Maak de configuratiedirectory en het bestand aan:
mkdir -p /data
cat > /data/openclaw.json << 'EOF'
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-opus-4-6",
"fallbacks": ["anthropic/claude-sonnet-4-5", "openai/gpt-4o"]
},
"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": {
"lastTouchedVersion": "2026.1.29"
}
}
EOF
Opmerking: Met OPENCLAW_STATE_DIR=/data is het configuratiepad /data/openclaw.json.
Opmerking: Het Discord-token kan komen van:
- Omgevingsvariabele:
DISCORD_BOT_TOKEN(aanbevolen voor geheimen) - Configuratiebestand:
channels.discord.token
Als je de omgevingsvariabele gebruikt, hoef je het token niet aan de configuratie toe te voegen. De gateway leest DISCORD_BOT_TOKEN automatisch.
Herstart om toe te passen:
exit
fly machine restart <machine-id>
6) Toegang tot de Gateway
Control UI
Open in de browser:
fly open
Of bezoek https://my-openclaw.fly.dev/
Plak je gateway-token (dat van OPENCLAW_GATEWAY_TOKEN) om te authenticeren.
Logs
fly logs # Live logs
fly logs --no-tail # Recente logs
SSH-console
fly ssh console
Probleemoplossing
”App is not listening on expected address”
De gateway bindt aan 127.0.0.1 in plaats van 0.0.0.0.
Oplossing: Voeg --bind lan toe aan je procescommando in fly.toml.
Health checks falen / connection refused
Fly kan de gateway niet bereiken op de geconfigureerde poort.
Oplossing: Zorg ervoor dat internal_port overeenkomt met de gateway-poort (stel --port 3000 of OPENCLAW_GATEWAY_PORT=3000 in).
OOM / Geheugenproblemen
Container blijft herstarten of wordt gekilld. Symptomen: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration, of stille herstarts.
Oplossing: Verhoog het geheugen in fly.toml:
[[vm]]
memory = "2048mb"
Of werk een bestaande machine bij:
fly machine update <machine-id> --vm-memory 2048 -y
Opmerking: 512MB is te weinig. 1GB kan werken maar kan OOM geven onder belasting of met uitgebreide logging. 2GB is aanbevolen.
Gateway-lockproblemen
Gateway weigert te starten met “already running”-fouten.
Dit gebeurt wanneer de container herstart maar het PID-lockbestand op het volume blijft staan.
Oplossing: Verwijder het lockbestand:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
Het lockbestand staat in /data/gateway.*.lock (niet in een subdirectory).
Configuratie wordt niet gelezen
Als je --allow-unconfigured gebruikt, maakt de gateway een minimale configuratie aan. Je aangepaste configuratie op /data/openclaw.json zou bij herstart gelezen moeten worden.
Controleer of de configuratie bestaat:
fly ssh console --command "cat /data/openclaw.json"
Configuratie schrijven via SSH
Het fly ssh console -C-commando ondersteunt geen shell-omleiding. Om een configuratiebestand te schrijven:
# Gebruik echo + tee (pipe van lokaal naar remote)
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Of gebruik sftp
fly sftp shell
> put /local/path/config.json /data/openclaw.json
Opmerking: fly sftp kan falen als het bestand al bestaat. Verwijder het eerst:
fly ssh console --command "rm /data/openclaw.json"
State blijft niet bewaard
Als je inloggegevens of sessies verliest na een herstart, schrijft de state-directory naar het container-bestandssysteem.
Oplossing: Zorg ervoor dat OPENCLAW_STATE_DIR=/data is ingesteld in fly.toml en deploy opnieuw.
Updates
# Laatste wijzigingen ophalen
git pull
# Opnieuw deployen
fly deploy
# Gezondheid controleren
fly status
fly logs
Machine-commando bijwerken
Als je het opstartcommando wilt wijzigen zonder volledige herdeployment:
# Machine-ID ophalen
fly machines list
# Commando bijwerken
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
# Of met geheugenverhoging
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
Opmerking: Na fly deploy kan het machine-commando worden gereset naar wat in fly.toml staat. Als je handmatige wijzigingen hebt gemaakt, pas ze opnieuw toe na deploy.
Privaat deployen (gehard)
Standaard wijst Fly publieke IP’s toe, waardoor je gateway bereikbaar is op https://your-app.fly.dev. Dit is handig, maar betekent dat je deployment vindbaar is door internetscanners (Shodan, Censys, etc.).
Voor een geharde deployment zonder publieke blootstelling, gebruik het privaat-template.
Wanneer privaat deployen gebruiken
- Je maakt alleen uitgaande gesprekken/berichten (geen inkomende webhooks)
- Je gebruikt ngrok of Tailscale-tunnels voor webhook-callbacks
- Je benadert de gateway via SSH, proxy of WireGuard in plaats van de browser
- Je wilt dat de deployment verborgen is voor internetscanners
Configuratie
Gebruik fly.private.toml in plaats van de standaardconfiguratie:
# Deployen met privaat-configuratie
fly deploy -c fly.private.toml
Of converteer een bestaande deployment:
# Huidige IP's weergeven
fly ips list -a my-openclaw
# Publieke IP's vrijgeven
fly ips release <public-ipv4> -a my-openclaw
fly ips release <public-ipv6> -a my-openclaw
# Schakel naar privaat-configuratie zodat toekomstige deploys geen publieke IP's toewijzen
# (verwijder [http_service] of deploy met het privaat-template)
fly deploy -c fly.private.toml
# Alleen privaat IPv6 toewijzen
fly ips allocate-v6 --private -a my-openclaw
Hierna zou fly ips list alleen een IP van het type private moeten tonen:
VERSION IP TYPE REGION
v6 fdaa:x:x:x:x::x private global
Toegang tot een privaat deployment
Aangezien er geen publieke URL is, gebruik een van deze methoden:
Optie 1: Lokale proxy (eenvoudigst)
# Lokale poort 3000 doorsturen naar de app
fly proxy 3000:3000 -a my-openclaw
# Open daarna http://localhost:3000 in de browser
Optie 2: WireGuard VPN
# WireGuard-configuratie aanmaken (eenmalig)
fly wireguard create
# Importeer in WireGuard-client, benader vervolgens via intern IPv6
# Voorbeeld: http://[fdaa:x:x:x:x::x]:3000
Optie 3: Alleen SSH
fly ssh console -a my-openclaw
Webhooks met privaat deployment
Als je webhook-callbacks nodig hebt (Twilio, Telnyx, etc.) zonder publieke blootstelling:
- ngrok-tunnel - Draai ngrok in de container of als sidecar
- Tailscale Funnel - Stel specifieke paden beschikbaar via Tailscale
- Alleen uitgaand - Sommige providers (Twilio) werken prima voor uitgaande gesprekken zonder webhooks
Voorbeeld voice-call-configuratie met ngrok:
{
"plugins": {
"entries": {
"voice-call": {
"enabled": true,
"config": {
"provider": "twilio",
"tunnel": { "provider": "ngrok" },
"webhookSecurity": {
"allowedHosts": ["example.ngrok.app"]
}
}
}
}
}
}
De ngrok-tunnel draait in de container en biedt een publieke webhook-URL zonder de Fly-app zelf bloot te stellen. Stel webhookSecurity.allowedHosts in op de publieke tunnel-hostname zodat doorgestuurde host-headers worden geaccepteerd.
Beveiligingsvoordelen
| Aspect | Publiek | Privaat |
|---|---|---|
| Internetscanners | Vindbaar | Verborgen |
| Directe aanvallen | Mogelijk | Geblokkeerd |
| Control UI-toegang | Browser | Proxy/VPN |
| Webhook-aflevering | Direct | Via tunnel |
Opmerkingen
- Fly.io gebruikt x86-architectuur (niet ARM)
- Het Dockerfile is compatibel met beide architecturen
- Voor WhatsApp/Telegram-onboarding, gebruik
fly ssh console - Persistente data staat op het volume op
/data - Signal vereist Java + signal-cli; gebruik een aangepaste image en houd het geheugen op 2GB+.
Kosten
Met de aanbevolen configuratie (shared-cpu-2x, 2GB RAM):
- ~$10-15/maand afhankelijk van gebruik
- De gratis tier bevat enige ruimte
Zie Fly.io pricing voor details.