Hosting
Fly.io
Objectif : Gateway OpenClaw exécuté sur une machine Fly.io avec stockage persistant, HTTPS automatique et accès à Discord/aux canaux.
Ce dont vous avez besoin
- CLI flyctl installée
- Compte Fly.io (l’offre gratuite convient)
- Authentification du modèle : clé API pour le fournisseur de modèle choisi
- Identifiants du canal : jeton de bot Discord, jeton Telegram, etc.
Parcours rapide pour débuter
- Clonez le dépôt, personnalisez
fly.toml - Créez l’application et le volume, définissez les secrets
- Déployez avec
fly deploy - Connectez-vous en SSH pour créer la configuration, ou utilisez l’interface de contrôle
Créer l’application Fly
git clone https://github.com/openclaw/openclaw.gitcd openclaw # choisissez votre propre nomfly apps create my-openclaw # 1 Go suffit généralementfly volumes create openclaw_data --size 1 --region iadChoisissez une région proche de vous. Options courantes : lhr (Londres), iad (Virginie), sjc (San José).
Configurer fly.toml
Modifiez fly.toml pour l’adapter au nom et aux exigences de votre application. Le fichier fly.toml suivi dans le dépôt est le modèle public présenté ci-dessous ; deploy/fly.private.toml est la variante renforcée sans adresse IP publique (consultez Déploiement privé).
app = "my-openclaw" # nom de votre applicationprimary_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"Le point d’entrée de l’image Docker OpenClaw est tini et exécute node openclaw.mjs gateway par défaut. Le paramètre Fly [processes] remplace le fichier Docker CMD (ici, il exécute directement node dist/index.js gateway ..., le même point d’entrée compilé) sans modifier ENTRYPOINT, si bien que le processus s’exécute toujours sous tini.
Paramètres clés :
| Paramètre | Raison |
|---|---|
--bind lan |
Se lie à 0.0.0.0 afin que le proxy Fly puisse atteindre le Gateway |
--allow-unconfigured |
Démarre sans fichier de configuration (vous le créez ensuite) |
internal_port = 3000 |
Doit correspondre à --port 3000 (ou OPENCLAW_GATEWAY_PORT) pour les vérifications d’état de Fly |
memory = "2048mb" |
512 Mo sont insuffisants ; 2 Go sont recommandés |
OPENCLAW_STATE_DIR = "/data" |
Conserve l’état sur le volume |
Définir les secrets
# obligatoire : jeton d’authentification du Gateway pour une liaison hors boucle localefly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) # clés API des fournisseurs de modèlesfly secrets set ANTHROPIC_API_KEY=example-anthropic-key-not-real # facultatif : autres fournisseursfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # jetons des canauxfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-tokenLes liaisons hors boucle locale (--bind lan) nécessitent un chemin d’authentification valide pour le Gateway. Cet exemple utilise OPENCLAW_GATEWAY_TOKEN, mais gateway.auth.password ou un déploiement de proxy de confiance hors boucle locale correctement configuré satisfont également cette exigence. Consultez Gestion des secrets pour le contrat SecretRef.
Traitez ces jetons comme des mots de passe. Préférez les variables d’environnement/fly secrets au fichier de configuration pour les clés API et les jetons, afin que les secrets ne figurent pas dans openclaw.json.
Déployer
fly deployLe premier déploiement construit l’image Docker. Vérifiez après le déploiement :
fly statusfly logsLes journaux de démarrage du Gateway affichent gateway ready une fois le service d’écoute HTTP/WebSocket opérationnel. La propre vérification d’état de Fly surveille internal_port = 3000 conformément à fly.toml ; la directive Docker HEALTHCHECK de l’image interroge également /healthz sur son port par défaut 18789, qui n’est pas utilisé ici puisque ce déploiement remplace le port du Gateway par --port 3000.
Créer le fichier de configuration
Connectez-vous en SSH à la machine pour créer une configuration correcte :
fly ssh consolemkdir -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": {}}EOFAvec OPENCLAW_STATE_DIR=/data, le chemin de configuration est /data/openclaw.json.
Remplacez https://my-openclaw.fly.dev par l’origine réelle de votre application Fly. Au démarrage, le Gateway initialise les origines locales de l’interface de contrôle à partir des valeurs d’exécution --bind et --port, afin que le premier démarrage puisse se poursuivre avant que la configuration existe ; toutefois, l’accès depuis un navigateur via Fly exige toujours que l’origine HTTPS exacte figure dans gateway.controlUi.allowedOrigins.
Le jeton Discord peut provenir de l’une des sources suivantes :
- Variable d’environnement
DISCORD_BOT_TOKEN(recommandée pour les secrets) ; inutile de l’ajouter à la configuration, le Gateway la lit automatiquement - Fichier de configuration
channels.discord.token
Redémarrez pour appliquer les modifications :
exitfly machine restart <machine-id>Accéder au Gateway
Interface de contrôle
fly openVous pouvez également consulter https://my-openclaw.fly.dev/.
Authentifiez-vous avec le secret partagé configuré : le jeton du Gateway provenant de OPENCLAW_GATEWAY_TOKEN, ou votre mot de passe si vous avez opté pour l’authentification par mot de passe.
Journaux
fly logs # journaux en directfly logs --no-tail # journaux récentsConsole SSH
fly ssh consoleRésolution des problèmes
« L’application n’écoute pas à l’adresse attendue »
Le Gateway se lie à 127.0.0.1 au lieu de 0.0.0.0.
Solution : ajoutez --bind lan à la commande du processus dans fly.toml.
Échec des vérifications d’état/refus de connexion
Fly ne peut pas atteindre le Gateway sur le port configuré.
Solution : vérifiez que internal_port correspond au port du Gateway (--port 3000 ou OPENCLAW_GATEWAY_PORT=3000).
Problèmes de mémoire insuffisante/OOM
Le conteneur redémarre continuellement ou est arrêté de force. Signes : SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration ou redémarrages silencieux.
Solution : augmentez la mémoire dans fly.toml :
[[vm]] memory = "2048mb"Ou mettez à jour une machine existante :
fly machine update <machine-id> --vm-memory 2048 -y512 Mo sont insuffisants. 1 Go peut fonctionner, mais risque d’entraîner une saturation de la mémoire en cas de charge élevée ou de journalisation détaillée. 2 Go sont recommandés.
Problèmes de verrouillage du Gateway
Le Gateway refuse de démarrer avec des erreurs indiquant qu’il est « déjà en cours d’exécution » après le redémarrage d’un conteneur.
Les fichiers de verrouillage d’exécution se trouvent dans <tmpdir>/openclaw-<uid>/gateway.<hash>.lock
et gateway.state.<hash>.lock (sous Linux :
/tmp/openclaw-<uid>/gateway.*.lock), et non sur le volume persistant /data. Ainsi,
un redémarrage complet du conteneur les supprime normalement avec le reste du
système de fichiers du conteneur. Si un verrou persiste (par exemple, un fly machine restart
qui conserve le système de fichiers du conteneur) et bloque le démarrage, supprimez-le
manuellement :
fly ssh console --command "rm -f /tmp/openclaw-*/gateway.*.lock"fly machine restart <machine-id>La configuration n’est pas lue
--allow-unconfigured contourne uniquement le contrôle au démarrage. Il ne crée ni ne répare /data/openclaw.json. Vérifiez donc que votre configuration réelle existe et comprend "gateway": { "mode": "local" } pour un démarrage local normal du Gateway.
Vérifiez que la configuration existe :
fly ssh console --command "cat /data/openclaw.json"Écriture de la configuration via SSH
fly ssh console -C ne prend pas en charge la redirection du shell. Pour écrire un fichier de configuration :
# echo + tee (canalisation de la machine locale vers la machine distante)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json" # ou sftpfly sftp shell> put /local/path/config.json /data/openclaw.jsonfly sftp peut échouer si le fichier existe déjà ; supprimez-le d’abord :
fly ssh console --command "rm /data/openclaw.json"L’état n’est pas conservé
Si vous perdez les profils d’authentification, l’état des canaux/fournisseurs ou les sessions après un redémarrage, le répertoire d’état est écrit dans le système de fichiers du conteneur plutôt que sur le volume.
Solution : vérifiez que OPENCLAW_STATE_DIR=/data est défini dans fly.toml, puis redéployez.
Mise à jour
git pullfly deployfly statusfly logsgit pull + fly deploy constitue ici le processus supervisé : il reconstruit l’image à partir du fichier Dockerfile, de sorte que la version de la CLI/du Gateway, l’image du système d’exploitation de base et toutes les modifications apportées au fichier Dockerfile sont mis à jour ensemble. openclaw update dans le conteneur en cours d’exécution n’est pas la même opération, car l’image est livrée sous la forme d’une arborescence dist/ construite avec Docker, sans extraction .git ni installation globale gérée par npm qu’elle pourrait détecter ; consultez Mise à jour pour ce processus sur les installations de type machine virtuelle.
Mise à jour de la commande de la machine
Pour modifier la commande de démarrage sans redéploiement complet :
fly machines listfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y # ou avec une augmentation de la mémoirefly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -yUne exécution ultérieure de fly deploy rétablit la commande de la machine à la valeur définie dans fly.toml ; appliquez de nouveau les modifications manuelles après le redéploiement.
Déploiement privé (renforcé)
Par défaut, Fly attribue des adresses IP publiques ; votre Gateway est donc accessible à l’adresse https://your-app.fly.dev et détectable par les scanners Internet (Shodan, Censys, etc.).
Utilisez deploy/fly.private.toml pour un déploiement renforcé sans adresse IP publique : il omet [http_service], de sorte qu’aucun accès entrant public n’est attribué.
Quand utiliser un déploiement privé
- Uniquement des appels/messages sortants (aucun Webhook entrant)
- Les tunnels ngrok ou Tailscale gèrent tous les rappels de Webhook
- L’accès au Gateway s’effectue par SSH, proxy ou WireGuard plutôt que depuis un navigateur
- Le déploiement doit être masqué aux scanners Internet
Configuration
fly deploy -c deploy/fly.private.tomlOu convertissez un déploiement existant :
# répertorier les adresses IP actuellesfly ips list -a my-openclaw # libérer les adresses IP publiquesfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw # passer à la configuration privée afin que les futurs déploiements ne réallouent pas d'adresses IP publiquesfly deploy -c deploy/fly.private.toml # allouer une adresse IPv6 privée uniquementfly ips allocate-v6 --private -a my-openclawAprès cela, fly ips list ne devrait afficher qu'une adresse IP de type private :
VERSION IP TYPE RÉGIONv6 fdaa:x:x:x:x::x privée globaleAccès à un déploiement privé
Option 1 : proxy local (le plus simple)
fly proxy 3000:3000 -a my-openclaw# ouvrir http://localhost:3000 dans un navigateurOption 2 : VPN WireGuard
fly wireguard create# importer dans un client WireGuard, puis accéder au service via l'adresse IPv6 interne# exemple : http://[fdaa:x:x:x:x::x]:3000Option 3 : SSH uniquement
fly ssh console -a my-openclawWebhooks avec un déploiement privé
Pour les rappels de Webhook (Twilio, Telnyx, etc.) sans exposition publique :
- Tunnel ngrok : exécutez ngrok dans le conteneur ou comme conteneur compagnon
- Tailscale Funnel : exposez des chemins spécifiques via Tailscale
- Trafic sortant uniquement : certains fournisseurs (Twilio) permettent les appels sortants sans Webhooks
Exemple de configuration des appels vocaux avec ngrok, sous plugins.entries.voice-call.config :
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}Le tunnel ngrok s'exécute dans le conteneur et fournit une URL publique de Webhook sans exposer l'application Fly elle-même. Définissez webhookSecurity.allowedHosts sur le nom d'hôte du tunnel afin que les en-têtes d'hôte transférés soient acceptés.
Compromis en matière de sécurité
| Aspect | Public | Privé |
|---|---|---|
| Analyseurs Internet | Détectable | Masqué |
| Attaques directes | Possibles | Bloquées |
| Accès à l'interface de contrôle | Navigateur | Proxy/VPN |
| Transmission des Webhooks | Directe | Via un tunnel |
Remarques
- Fly.io utilise l'architecture x86 ; le Dockerfile est compatible avec x86 et ARM.
- Pour l'intégration de WhatsApp/Telegram, utilisez
fly ssh console. - Les données persistantes résident sur le volume à l'emplacement
/data. - Signal nécessite signal-cli (une CLI basée sur Java) dans l'image ; utilisez une image personnalisée et conservez au moins 2GB de mémoire.
Coût
Avec la configuration recommandée (shared-cpu-2x, 2GB de RAM), prévoyez environ $10-15/mois selon l'utilisation ; l'offre gratuite couvre une partie de l'allocation de base. Consultez les tarifs de Fly.io pour connaître les tarifs actuels.
Étapes suivantes
- Configurez les canaux de messagerie : Canaux
- Configurez le Gateway : Configuration du Gateway
- Maintenez OpenClaw à jour : Mise à jour