OpenClaw est installé, mais vous refusez d'exposer le Gateway sur l'interface publique ? Sur un VPS type Ubuntu 24.04, on bloque souvent sur l'adresse d'écoute, les redémarrages prévisibles via systemd, et la manière dont Cloudflare Tunnel (ou équivalent) ne publie que le loopback derrière un nom contrôlé. Cet article complète les guides Docker production et multi-plateforme par une voie bare metal + service système + tunnel : socle d'environnement, paramètres Gateway, exemple d'unité systemd, routage ingress et diagnostic par symptômes, avec une topologie courante associant un Mac distant stable pour les charges qui vivent naturellement sur l'écosystème Apple (builds, previews, chaîne créative).
Le guide multi-plateforme vise le premier démarrage. La variante Docker s'adresse aux équipes déjà structurées autour des conteneurs et de Compose. Ici, l'angle est Ubuntu 24.04 nu, peu d'abstraction, systemd pour la résilience et le boot, puis Cloudflare Tunnel (ou reverse proxy maison) afin de sortir TLS et contrôle d'accès du runtime applicatif. Les trois approches se combinent : validez d'abord sur bare metal, conteneurisez ensuite si besoin.
Six écarts de modèle fréquents dans nos tickets. Sans les corriger, les checklists suivantes manquent de sens.
« curl OK » assimilé à « sûr en prod » : écouter sur 0.0.0.0 sans frontal place auth et TLS sur les défauts de l'app ; un simple décalage de config ouvre le balai réseau.
Négliger le couplage Node / glibc : binaires périmés ou NODE_OPTIONS incohérents sur 24.04 donnent un faux positif « ça marche en local, jamais sous systemd ».
Répertoires et droits jetés sous /root : après upgrade ou rotation des logs, la config ne se lit plus — systemd boucle, les journaux noient le signal.
Santé = présence du processus seule : sans readiness HTTP ni test du plan de contrôle du modèle, le load balancer envoie encore, le tunnel répond 502 — vous déboguez la mauvaise couche.
Tunnel vert, mauvais port : si l'ingress cloudflared ne correspond pas au listen réel du Gateway, le DNS résout mais le loopback ne colle pas.
Passerelle Linux comme exécuteur universel : forcer Xcode, simulateur ou spécificités Apple Silicon sur le VPS fait croire à « OpenClaw instable » — c'est un problème de placement dans la pile.
Si « loopback + tunnel » correspond à votre politique, poursuivez avec la baseline et les commandes ci-dessous.
Ne réduisez pas le choix à la vitesse d'installation : alignez surface d'attaque, observabilité et retour arrière sur une même ligne. Le tableau sert aux revues ; remplacez ports et tags d'images par vos valeurs.
| Axe | Gateway public | Docker / Compose | systemd + loopback + Tunnel |
|---|---|---|---|
| Exposition | Maximale ; TLS et pare-feu côté app | Dépend des ports publiés et du mode réseau ; host risqué | 127.0.0.1 seulement ; entrée publique au tunnel / edge |
| Certificats | ACME maison ou rotation manuelle | Souvent Traefik / Caddy / LB cloud | TLS terminé au bord Cloudflare (ou équivalent) |
| Redémarrage / debug | Superviseurs externes ou manuel | Politiques restart et logs à concevoir | systemd + journal ordonnés |
| Profil d'équipe | PoC minimal, pas la prod | Gouvernance conteneurs mature | Un VPS, scripts reproductibles, PME |
La question n'est pas « joignable oui/non », mais « qui est autorisé, sur quel chemin » — réduire l'écoute au loopback déplace cette décision vers l'edge, où TLS et politiques sont mieux maîtrisés.
Sur Ubuntu 24.04 LTS, suivez la branche LTS majeure actuelle de Node.js (début 2026 souvent 22.x ; référence nodejs.org). nvm, fnm ou NodeSource conviennent ; en production épinglez le minor et planifiez les montées de version. Le paquet distro seul est en général trop vieux pour le Gateway.
Pare-feu : SSH par clé, ufw en deny entrant par défaut, aucune règle publique sur le port métier du Gateway — l'extérieur transite par le tunnel. Debug direct : fenêtre allowlist ou bastion, date de retrait notée dans le journal de changements.
Utilisateur et arborescence dédiés : ex. utilisateur openclaw, état sous /var/lib/openclaw, config /etc/openclaw (640 / 750), pas mélangé à root.
Version Node figée et lockfile : conservez package-lock.json ou pnpm-lock.yaml ; en prod npm ci ou équivalent — pas de major accidentel.
glibc et modules natifs : installation propre et smoke test sur la machine cible pour écarter dlopen.
Fuseau : timedatectl en UTC ou standard d'équipe — corrélation avec logs tunnel / edge.
ufw minimal : ufw allow OpenSSH puis ufw enable ; ports métier fermés ; ss -tlnp confirme l'absence d'écoute publique du Gateway.
Endpoint de santé : avant le tunnel, documentez curl -fsS http://127.0.0.1:PORT/health (chemin selon config) dans le runbook ; alignez ExecStartPost ou sondes externes.
Note : les sous-commandes et noms de fichiers OpenClaw suivent la doc amont ; chemins et ports dans l'unit et le YAML sont des placeholders à adapter avant activation.
Écoute : en production privilégiez 127.0.0.1:PORT ; socket Unix si supporté. Secrets : fichier d'environnement, jamais en config lisible par tous ; rotation : nouveau jeton, redémarrage progressif, suppression de l'ancien. Santé : au minimum processus + readiness HTTP ou atteinte du plan de contrôle du modèle — sinon le tunnel ne dit que « injoignable », pas « mauvaise couche ».
[Unit] Description=OpenClaw Gateway (loopback) After=network-online.target Wants=network-online.target [Service] User=openclaw Group=openclaw WorkingDirectory=/var/lib/openclaw EnvironmentFile=-/etc/openclaw/gateway.env # Remplacez ExecStart par la commande réelle de la documentation ExecStart=/usr/bin/node /opt/openclaw/gateway.mjs --config /etc/openclaw/gateway.yaml Restart=on-failure RestartSec=5 LimitNOFILE=1048576 # Logs : journal en priorité ; fichiers avec logrotate et droits StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
Enchaînement conseillé : systemctl daemon-reload → systemctl enable --now openclaw-gateway → systemctl status jusqu'à stabilité → curl santé en local → puis cloudflared.
tunnel: <YOUR_TUNNEL_ID>
credentials-file: /etc/cloudflared/<YOUR_TUNNEL_ID>.json
ingress:
- hostname: claw.example.com
service: http://127.0.0.1:8787
- service: http_status:404
Attention : le JSON d'identifiants du tunnel est lisible uniquement par root ou un utilisateur dédié ; pas dans les couches d'image ni les logs CI publics. Avec Nginx/Caddy, gardez TLS en périphérie et amont loopback uniquement.
Ordre de lecture des journaux : ① journalctl -u openclaw-gateway -b --no-pager (boucles, env) ; ② répertoire applicatif ; ③ journalctl -u cloudflared ; ④ curl -v local et externe — processus vs routage.
Ports : avec EADDRINUSE, ss -tlnp pour le détenteur ; changez de port → mettez à jour ingress et sondes. Droits : EACCES → propriétaire/groupe des configs et clés ; l'utilisateur systemd doit lire. Tunnel : 502 externe, curl local OK → ingress, session Cloudflare, DNS. Modèles : timeouts/401 → curl baseline fournisseur depuis le serveur (pas de secrets dans l'historique shell).
Schéma fréquent : VPS Linux pour le Gateway public, files d'attente et orchestration légère ; Mac distant stable (Apple Silicon physique) pour Xcode, simulateur et chaîne réservée à macOS — ce qui colle aux workflows créatifs et aux builds Apple. Les tâches lourdes partent sur le Mac : objectif « pas de bind public sur le Gateway » sans forcer Linux hors de son rôle. Mac comme nœud d'exécution commandable, Linux comme plan de contrôle que vous opérez ; lien SSH, file ou tunnel privé. Isolez les domaines de panne : une chute de passerelle ne doit pas effacer les caches de build Mac ; la maintenance Mac ne doit pas couper l'entrée API entière.
127.0.0.1 et un port — éviter un bind dual-stack involontaire sur toutes interfaces.Restart=on-failure + RestartSec=5 pour des journaux lisibles ; StartLimitIntervalSec si besoin.http://127.0.0.1:PORT plutôt que localhost pour éviter ::1 quand l'app n'écoute qu'en IPv4.Un seul VPS Linux + tunnel convient au plan de contrôle et à l'agrégation d'API ; la CI/CD iOS, les simulateurs, Metal et la chaîne Xcode heurtent vite des limites : compromis sur l'environnement headless distant, ou coût continu d'images et d'exploitation. Placer la charge lourde sur un Mac distant dédié, avec fenêtres de maintenance prévisibles, tout en gardant systemd et tunnel sur la passerelle, clarifie la zone d'impact. Pour des agents et pipelines durables, la location cloud de Mac mini NodeMini est souvent le meilleur compromis — le contrôle reste sur votre VPS, l'exécution sur du matériel et des durées alignés sur l'écosystème Apple.
En production, fortement recommandé : écoute loopback uniquement ; TLS et politique via tunnel ou reverse proxy. Port public : listes blanches, débit, audit — souvent plus lourd qu'un tunnel. Autres articles : colonne OpenClaw.
curl vers le loopback sur le serveur ; puis ingress et identifiants du tunnel ; enfin modèles ou DNS. Avant de commander des nœuds, consultez les tarifs de location pour durée et région.
SSH, VNC et incidents courants : centre d'aide ; liste des billets : accueil du blog.