Objectifs et prérequis
Objectif : réduire les échecs de build « cold pull » en pré-chauffant le cache Docker du Mac avant que les runners CI ne consomment la file ; centraliser la preuve d’exécution (digest, durée, code erreur) dans un format unique consommable par vos pipelines.
Prérequis : un projet Harbor où vous pouvez créer un endpoint de notification ; un Mac avec Docker Desktop ou moteur équivalent fonctionnel ; Node.js 22 LTS (ou 24) pour OpenClaw ; un chemin HTTPS public (tunnel ou reverse proxy) vers le handler ; un jeton CI distinct pour la callback (ne jamais réutiliser le secret Harbor comme Bearer vers un tiers).
- Beaucoup d’équipes installent d’abord curl et les utilitaires de base via le gestionnaire de paquets du système avant d’ajouter Node.
- La séquence
openclaw onboardsuivie deopenclaw doctorest courante ; en production, l’optionopenclaw onboard --install-daemon(lorsque proposée par votre version) ou un LaunchAgent dédié évite de lier la passerelle à une session graphique. - Une auto-vérification typique combine
openclaw doctoretcurlvershttp://127.0.0.1:<PORT>/healthavec en-têteAuthorization: Bearer …si votre passerelle l’exige.
À ce stade, validez docker info, docker login vers Harbor avec un compte de pull seule, et notez l’URL exacte du registre (sans supposer que l’hôte du portail Web soit identique à l’endpoint de pull).
Harbor Webhook : champs d’événement et checklist de signature
Dans Harbor, créez une notification de projet pointant vers https://…/hooks/harbor (chemin d’exemple). Limitez les types d’événements — en pratique PUSH_ARTIFACT ou l’équivalent « nouvel artefact » — pour éviter le bruit des suppressions ou scans.
| Zone du JSON | Intérêt pour le pré-tirage | Note |
|---|---|---|
event_type | Filtrage côté handler | Refuser tôt les types non gérés |
repository.namespace + repository.name | Construire la référence d’image | Préférer la forme normalisée attendue par docker pull |
resources / digest | Idempotence et corrélation | Journaliser digest + tag pour dédoublonner |
occur_at ou horodatage équivalent | Ordre et anti-rejeu | Comparer à une fenêtre courte si vous en avez une |
- Secret partagé : en-tête dédié (
X-Harbor-Signatureou nom convenu) ou jeton Bearer attendu par OpenClaw — documentez la variante retenue. - Si vous utilisez un HMAC : calculez-le sur le corps brut reçu du socket HTTP, pas sur l’objet JSON ré-encodé (sinon signature systématiquement fausse).
- Refuser les requêtes sans
Content-Type: application/jsoncohérent si votre parser l’exige. - Limiter la taille du corps et journaliser un
event_idsynthétique pour corréler Harbor ↔ Mac ↔ CI.
Test manuel : envoyez un POST de laboratoire avec curl en reprenant les mêmes en-têtes que Harbor ; comparez le code HTTP et le corps de réponse avec ce qu’affiche l’onglet « deliveries » côté Harbor.
Script de pré-tirage sur Mac distant : concurrence, timeout et quota disque
Après validation du webhook, le handler résout la liste d’images à pré-tirer (image poussée + dépendances figées dans un fichier versionné ou une table interne). Le script shell ne doit pas « tirer à l’infini » : exposez des variables d’environnement pour rendre le comportement observable et borné.
| Variable | Rôle | Valeur de départ indicative |
|---|---|---|
PREFETCH_CONCURRENCY | Nombre maximal de docker pull parallèles | 2 sur Mac partagé, 3–4 sur nœud dédié NVMe |
PULL_TIMEOUT_SEC | Timeout par image (outil timeout ou client) | 300–900 s selon couches |
MIN_FREE_GB | Seuil df avant d’accepter un nouveau pull | 15–40 Go selon builds |
Si l’espace libre passe sous MIN_FREE_GB, sortez avec code non nul ou enregistrez un statut skipped_disk dans la synthèse — l’important est que la CI puisse interpréter explicitement l’état. Un docker image prune ciblé (étiquettes non utilisées) peut être autorisé uniquement derrière un drapeau explicite pour éviter les surprises sur un hôte partagé.
Sur un Mac cloud loué pour CI, le disque et la latence vers Harbor sont plus stables qu’une machine personnelle : vous évitez les mises en veille et les quotas imprévisibles du poste développeur.
Routage passerelle OpenClaw et modèle de synthèse d’échec
Exposez une route stable du type /hooks/harbor (nom exact selon votre configuration OpenClaw). Le flux recommandé : vérifier secret / signature → parser le JSON → répondre 202 Accepted si le pré-tirage peut dépasser le timeout HTTP de Harbor, puis exécuter le pull en tâche de fond ; sinon répondez 200 avec un corps court une fois le pull terminé.
Le handler ne doit pas pouvoir ouvrir des URL arbitraires vers Internet : limitez-le aux hôtes Harbor (portail + registre de pull, y compris sous-domaines de couches), au fournisseur d’identité si vous utilisez OIDC pour Docker ou Harbor, et à l’URL HTTPS de callback CI documentée. Sur macOS, combinez pare-feu local, profil réseau du fournisseur cloud et règles proxy sortant ; refusez par défaut le reste pour réduire le risque SSRF si un corps de webhook était forgé.
- Séparez le jeton callback CI du secret webhook Harbor et du PAT docker login.
- Journalisez les échecs DNS/TLS avec le nom d’hôte demandé pour valider rapidement un oubli dans la liste blanche.
Quelle que soit l’issue, postez vers votre CI un JSON uniforme (second curl ou client HTTP) :
Le champ error_code doit provenir d’une liste fermée (auth_failed, pull_timeout, disk_threshold, invalid_payload, …) pour faciliter les alertes. Gardez le jeton CI dans un fichier permissions 600 lu par le daemon, distinct du secret Harbor.
Documentez dans votre runbook le mapping « route → handler → script » afin qu’un remplaçant puisse reproduire le diagnostic sans lire le code.
FAQ — erreurs fréquentes (authentification, timeout, disque plein)
401 ou signature rejetée alors que Harbor affiche « delivery success »
Harbor peut recevoir un 200 d’un reverse proxy alors que le handler interne a rejeté la requête. Comparez les journaux des deux couches ; vérifiez que le secret configuré dans Harbor correspond octet pour octet à celui du service ; recalculez le HMAC sur le corps brut.
docker pull bloque ou dépasse le timeout
Baissez PREFETCH_CONCURRENCY ; augmentez PULL_TIMEOUT_SEC avec plafond ; contrôlez proxy sortant et certificats MITM ; assurez-vous que la liste blanche inclut tous les hôtes de registre (sous-domaines de blobs).
Disque plein ou MIN_FREE_GB déclenché en boucle
Vérifiez la croissance des couches intermédiaires ; planifiez un prune contrôlé ou augmentez le volume ; évitez de cumuler plusieurs dépôts sur le même Docker root sans quotas par équipe.
/health vert mais aucun événement Harbor dans les logs
Chemin public différent du chemin interne ; ACL IP ; en-tête Host après TLS ; webhook pointant vers l’ancien tunnel fermé.
Synthèse et orientation achat
En bref : verrouillez le contrat Harbor (événements, champs, signature sur corps brut), bornez le pré-tirage (concurrence, timeout, disque), routez proprement via OpenClaw et unifiez la synthèse JSON vers la CI ; refermez le tout avec une liste blanche sortante explicite. Pour monter ce scénario sur un hôte toujours joignable, les pages achat, tarifs, aide, accueil et le blog technique MacPull sont consultables sans connexion.
Louez un Mac cloud comme nœud de pré-tirage Harbor
Pages ouvertes sans login : accueil, centre d’aide, achat, tarifs, blog technique (série OpenClaw 2026).