openclaw gateway status en JSON, enchaîner openclaw doctor, produire une empreinte réseau sur le port par défaut 18789 (lsof), puis croiser avec une sonde HTTP. L’objectif est d’aligner la CI sur la même logique que l’exploitation launchd : chemins Node absolus (hors nvm seul), variables cohérentes entre shell et plist, et mode headless pour éviter tout assistant graphique. Une passerelle stable sur le runner, après pré-tirage des dépendances et caches, permet à cette porte de refléter la réalité production et d’alimenter des synthèses CI courtes sans relancer le service à chaque commentaire de merge request.
Trois risques sans cette chaîne
- Dérive PATH : le job voit
openclawvianvmalors que launchd pointe vers un autre préfixe npm — les verts CI ne correspondent plus au daemon réel. - Conflit silencieux sur 18789 : une instance résiduelle ou un lab occupe le port ; le JSON « processus up » ne dit pas quel binaire écoute réellement.
- Cold start : sans préchauffage npm ou modèles,
doctoret les sondes timeout avant la fin du merge — faux négatifs qui masquent les vraies régressions de configuration.
Pour compléter la validation purement statique, reportez-vous à openclaw config validate en porte CI et, pour le cycle de vie daemon et le rechargement des routes, à passerelle, hybrid reload et jeton. La séquence ci-dessous reste volontairement courte à copier dans un script de pipeline.
Prérequis alignés « ops passerelle »
Node : viser 22.16+ ou 24 selon votre politique ; journaliser node -v et le chemin absolu du binaire (command -v node ou type -P node). OpenClaw : même révision que celle déployée sur le Mac hébergé. Répertoires : par job, OPENCLAW_HOME et OPENCLAW_CONFIG_HOME isolés (voir aussi les guides d’embarquement non interactif). launchd : si vous comparez CI et production, imprimez le PATH et which openclaw du job comme référence pour remplir ProgramArguments et EnvironmentVariables du plist — le shell SSH interactif n’est pas contractuel.
| Élément | Cible | Contrôle |
|---|---|---|
| Mode headless | Pas de TTY / wizard | CI=true ; options --format json sur gateway status (voir --help de votre build). |
| Port | 127.0.0.1:18789 par défaut | Variable PORT ou config si vous déplacez l’écoute ; mettre à jour lsof et curl ensemble. |
| Jeton passerelle | OPENCLAW_GATEWAY_TOKEN cohérent | Même valeur (hors log) entre étape shell et contexte launchd si vous testez le daemon. |
Sur le terrain, l’ordre « status puis doctor » reflète l’habitude des équipes qui exploitent la passerelle comme un service : d’abord une vue lecture seule de l’état d’écoute et de la version, ensuite les diagnostics plus lourds qui touchent fichiers, permissions et connectivité fournisseurs. En CI, ce découplage permet d’attacher à la merge request un JSON court (diffable) avant les journaux longs de doctor, ce qui accélère la lecture humaine des échecs sans sacrifier la profondeur du diagnostic.
Checklist d’exécution (pipeline)
Adaptez CI_ARTIFACT_DIR et le port. L’ordre compte : empreinte port après statut JSON pour corréler PID et fichier JSON dans le même artefact.
- Isoler
OPENCLAW_HOMEpar identifiant de job pour éviter les collisions avec un daemon persistant. - Forcer
CI=trueet les drapeaux JSON documentés pourgateway status(headless). - Archiver
gateway-status.jsonavant toute mutation de config. - Enchaîner
doctor --deeppuisconfig validate; traiter tout code de sortie non nul comme échec de porte. - Capturer
lsofsur 18789 : comparer la commande affichée au binaireopenclawattendu ou documenter un conflit. - Terminer par
curlsur/healthavec en-tête Bearer si votre passerelle l’exige.
Critères de santé (barème minimal)
Les champs exacts du JSON varient selon la version ; fixez en interne une liste stable (par exemple : état du processus, adresse d’écoute, version CLI). En complément, exigez HTTP 200 sur /health et un corps JSON parseable. Si le statut CLI annonce « prêt » mais curl échoue, conservez gateway-status.json, lsof-18789.txt et la sortie curl dans un seul zip d’artefact pour le post-mortem.
| Signal | Vert | Rouge / creuser |
|---|---|---|
gateway status JSON | Champs d’état attendus présents et cohérents avec le port configuré | Champ manquant, incohérence port / bind, version CLI différente du lockfile infra |
lsof 18789 | Un seul PID, commande alignée avec votre binaire | PID inconnu, double écoute, autre outil (proxy, lab) |
GET /health | 200 + JSON court | 401 sans Bearer, ECONNREFUSED, timeout après pré-tirage raisonnable |
Messages fréquents et lecture opérationnelle
| Observation | Interprétation probable | Action |
|---|---|---|
address already in use / 18789 occupé | Instance résiduelle, second label launchd, ou job parallèle | lsof puis stop ciblé ; pour la fumée CI, utiliser un port dédié et le refléter partout |
401 Unauthorized sur /health | Jeton absent ou différent entre shell et daemon | Vérifier OPENCLAW_GATEWAY_TOKEN dans plist vs job ; aligner l’en-tête Authorization |
command not found: openclaw | PATH minimal sous agent CI | Chemin absolu dans le script ou EnvironmentVariables calqué sur command -v openclaw figé |
Doctor OK, validate KO sur invalid-key | Schéma YAML plus strict que l’instance chaude | Corriger la clé ; croiser avec la porte validate dédiée |
| Timeouts massifs sans pré-tirage | Cold start réseau ou disque | Étape de warm-up caches / modèles avant la porte (voir guide embeddings) |
Valeur pour les synthèses CI
En publiant gateway-status.json, doctor.log, validate.json, lsof-18789.txt et health.json comme artefacts, un webhook ou une étape finale peut poster sur la merge request un résumé une ligne (« vert : bind 18789 + health 200 » / « rouge : PID 12345 inconnu sur 18789 ») sans ré-exécuter la passerelle. Sur Mac distant partagé, cela réduit la contention disque et réseau et rend les retours d’astreinte actionnables. Le pré-tirage des dépendances en amont stabilise les timings : la porte mesure une configuration réaliste plutôt qu’un premier démarrage bruyant.
- HowTo : une entrée
HowToavecstepnumérotées reprend la checklist machine pour les moteurs enrichis. - FAQPage : bloc séparé
FAQPageavec paires Question /acceptedAnswerpour les cas limites (PATH, conflit port, JSON vs HTTP). - Conserver BlogPosting + BreadcrumbList sur cette URL canonique pour cohérence avec le reste du blog MacPull.
FAQ
Faut-il exiger un lsof vide avant de démarrer la passerelle de test ?
Seulement si votre politique impose un hôte « neutre » ; sinon documentez le PID attendu (daemon partagé) et faites échouer la porte lorsque le PID ou la commande ne correspond pas au profil autorisé.
Les drapeaux --format json suffisent-ils pour le headless ?
Ils orientent la sortie ; combinez-les avec CI=true et l’absence de variables qui déclencheraient un wizard. Vérifiez la sortie de openclaw gateway status --help sur votre build figée.
Où stocker les artefacts pour la conformité ?
Dans le magasin d’artefacts du orchestrateur (GitLab, GitHub Actions, etc.) avec rétention alignée sur la MR ; jamais de secrets en clair dans les journaux attachés.
Synthèse
Enchaîner statut JSON, doctor, validate et empreinte lsof sur 18789 donne une porte pré-merge lisible par les machines et par les humains, calquée sur l’exploitation launchd et sur des chemins Node non ambigus. Sans compte obligatoire : accueil, achat, tarifs, centre d’aide, blog.
Louez un Mac cloud pour figer passerelle et portes
Découvrez l’offre MacPull pour exécuter ces étapes sur un runner Apple Silicon dédié, avec documentation en ligne.