AI Frontier

Passerelle OpenClaw sur macOS en 2026 : liaison de port EADDRINUSE, diagnostics lsof, plists LaunchAgent et alignement des sondes de santé

MacHTML Lab2026.05.11~30 min de lecture

Rien ne fige un déploiement OpenClaw aussi vite que Error: listen EADDRINUSE: address already in use. En 2026, les équipes confondent encore « port occupé » et « API modèle en panne », tournent les clés API des heures et oublient qu’un node zombie du smoke test d’hier tient encore TCP 8787. macOS complique : launchd relance un job avant que l’ancien socket soit totalement libéré, plusieurs profils partagent un Mac mini loué, et les sondes synthétiques curlent souvent 127.0.0.1 alors que la passerelle écoute sur une IP LAN. Ce guide propose une triage reproductible—lsof d’abord, parité plist ensuite, alignement des sondes enfin—reliée à doctor et diagnostic passerelle, premier lancement LaunchAgent et surveillance de santé pour arrêter les suppositions.

Traitez les collisions de ports comme des incidents de capacité : notez interface, PID et label LaunchAgent pour des post-mortems courts.

Sans plage de ports documentée, le blue/green du week-end se termine souvent par deux instances sur le même numéro—anticipez avec un tableau partagé.

Symptômes ressemblant à des pannes amont

Les clients voient refus de connexion, curl vide ou tableaux « passerelle hors ligne » avec CPU au repos. Avant d’accuser les fournisseurs de modèles, vérifiez si le serveur HTTP a atteint LISTEN. Si le processus meurt au boot, les journaux peuvent s’arrêter avant la bannière—seul errno reste. Collectez stderr via StandardErrorPath et corrélez avec launchctl print.

Sur Mac mini partagés, les sessions npm run dev oubliées sont le coupable habituel ; elles n’apparaissent pas dans Grafana car jamais instrumentées.

Les erreurs DNS ou TLS produisent des nuages de symptômes similaires : vérifiez d’abord la socket, puis TLS, puis l’amont.

Recettes lsof en une minute

lsof -nP -iTCP:8787 -sTCP:LISTEN

-n évite les résolutions DNS lentes ; -P affiche les ports numériques. Pour un PID node inconnu, capturez ps -p PID -o args= avant kill. Si rien n’écoute mais les clients échouent, vérifiez HTTPS client contre HTTP passerelle.

Pour IPv6 uniquement, ajoutez lsof -nP -i6TCP:8787 ; certaines piles Node dupliquent l’écoute dual-stack.

ProgramArguments LaunchAgent et drapeaux de port

Les plists passent souvent --port deux fois : wrapper et modèle copié. Le dernier argument gagne silencieusement. Une seule source de vérité : variables d’environnement ou arguments explicites. Après édition, launchctl bootout puis bootstrap pour fermer l’ancien socket.

Validez WorkingDirectory vers le checkout contenant la package.json attendue ; cwd erroné + npx peut recréer un écouteur par défaut.

127.0.0.1 versus 0.0.0.0 versus IP LAN

La loopback limite le scan LAN mais casse les sondes depuis d’autres hôtes. 0.0.0.0 exige discipline pare-feu. Une IP bureau fixe casse au renouvellement DHCP. Documentez le contrat dans le runbook et reflétez-le dans les attentes openclaw doctor.

Sondes de santé trompeuses

Des moniteurs qui curl http://127.0.0.1:8787/readyz restent verts quand les utilisateurs distants échouent sur 10.0.40.12:8787 à cause de VPN split ou routage. Alignez l’IP source des sondes sur le chemin réel ou tunnelisez via le même bastion. Exportez gateway_bind_interface au démarrage pour Grafana.

Un health L4 peut rester vert alors que l’auth L7 échoue : combinez socket + petit appel HTTP authentifié.

Matrice de décision

ScénarioBind préféréPoint de vigilance
Lab portable solo127.0.0.1Bascule avant démos distantes
Mac mini partagé derrière pare-feuIP LAN + liste blancheRéservations DHCP
Bord public avec reverse proxyloopback + nginx frontalÉviter d’exposer la passerelle sur l’interface publique

TIME_WAIT et redémarrages rapides

Les scripts de déploiage qui redémarrent toutes les 30 secondes laissent l’ancien PID en TIME_WAIT jusqu’à ~60 secondes ou épuisent les ports éphémères. Insérez ~5 secondes entre bootout et bootstrap, ou incrémentez temporairement le port admin.

Pièges du pare-feu applicatif

macOS demande l’autorisation entrante pour chaque nouveau chemin binaire Node. Refus local = bind OK mais SYN distants en timeout, comme un conflit de port. Standardisez chemins ou signatures pour éviter les dialogues en cascade lors des upgrades.

Plusieurs passerelles sur un Mac

Le blue/green exige des ports distincts (8787/8788) et des labels uniques. Réservez des plages : 8700–8799 OpenClaw, 8800–8899 mocks—sans feuille partagée, les prestataires choisissent au hasard.

Staging + production sur un hôte : séparez utilisateurs ou journaux pour garder lsof lisible.

launchctl kickstart et écouteurs résiduels

Après libération, préférez launchctl kickstart -k gui/$UID/com.example.openclaw pour que launchd envoie SIGKILL aux enfants récalcitrants. Sans -k, un thread middleware peut garder le FD malgré « shutdown complete ». Archivez un extrait de launchctl print avant/après pour prouver runningnot running.

Ports clients éphémères et tempêtes sortantes

Le fan-out d’outils ouvre des milliers de connexions sortantes ; macOS peut épuiser les plages éphémères alors que LISTEN semble sain. Ne confondez pas EADDRINUSE côté client avec un conflit d’écouteur. Surveillez sysctl net.inet.ip.portrange.hifirst pour les runners CI colocalisés.

Logs structurés sur échec de bind

Émettez du JSON avec event="bind_failed", errno, hôte, port, hash d’argv. Les post-mortems ne doivent pas redécouvrir par SSH. Associez errno 48 (EADDRINUSE) à la commande lsof sur la même ligne de log.

Pourquoi la CI Linux rate les courses macOS

Les conteneurs redémarrent vite ; les namespaces réseau diffèrent des sessions GUI macOS. Traitez Linux comme contrôle de compilation ; gardez un smoke bind sur matériel Apple avant de fusionner des plists. Une location Mac mini d’une journée coûte environ une heure-ingénieur et boucle la preuve.

FAQ

macOS réutilise-t-il un port instantanément ?

Non ; attendez après des redémarrages à haut churn ou changez de port admin.

Pourquoi la santé est verte et les utilisateurs échouent ?

Les interfaces des sondes et des clients divergent.

0.0.0.0 est-il plus sûr que la loopback ?

Non—surface plus large ; ajoutez des règles pare-feu.

Quand louer un Mac mini ?

Quand il faut reproduire la sémantique des sockets macOS hors portable.

Les guerres de ports sont ennuyeuses mais coûteuses. Un Mac mini Apple Silicon loué chez MacHTML—environ 16,9 USD par jour—offre le même cycle launchd, les mêmes défauts de socket et les mêmes invites pare-feu que la production, sans expédier du matériel. Montez-le pour une semaine de release, collectez des preuves lsof, puis arrêtez la location.

Le silence thermique aide lors de longues sessions SSH de tests de bind répétés.

Reproduire les problèmes de bind OpenClaw sur macOS réel

Louez un Mac mini cloud pour valider ports, plists LaunchAgent et sondes avec un comportement de sockets fidèle à macOS.

QA port passerelle
dès ~16,9 $/jour