Ce tutoriel décrit un scénario minimal reproductible : lorsqu’un artefact est poussé dans Harbor, un Webhook atteint la passerelle OpenClaw sur un Mac distant, un script déclenche le pré-tirage des images dépendantes, puis un JSON de synthèse (succès ou échec) est renvoyé vers votre orchestrateur CI interne, le tout derrière une liste blanche sortante. Pour approfondir registres et matrice transfrontière, voir GHCR et registry privé ; pour le disque sous charge, concurrence et quota disque ; pour la passerelle, sécurisation OpenClaw.

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).

Références de flux « communauté 2026 » (non bloquantes)
  • 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 onboard suivie de openclaw doctor est courante ; en production, l’option openclaw 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 doctor et curl vers http://127.0.0.1:<PORT>/health avec en-tête Authorization: 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 JSONIntérêt pour le pré-tirageNote
event_typeFiltrage côté handlerRefuser tôt les types non gérés
repository.namespace + repository.nameConstruire la référence d’imagePréférer la forme normalisée attendue par docker pull
resources / digestIdempotence et corrélationJournaliser digest + tag pour dédoublonner
occur_at ou horodatage équivalentOrdre et anti-rejeuComparer à une fenêtre courte si vous en avez une
Checklist signature / authentification
  • Secret partagé : en-tête dédié (X-Harbor-Signature ou 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/json cohérent si votre parser l’exige.
  • Limiter la taille du corps et journaliser un event_id synthé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é.

VariableRôleValeur de départ indicative
PREFETCH_CONCURRENCYNombre maximal de docker pull parallèles2 sur Mac partagé, 3–4 sur nœud dédié NVMe
PULL_TIMEOUT_SECTimeout par image (outil timeout ou client)300–900 s selon couches
MIN_FREE_GBSeuil df avant d’accepter un nouveau pull15–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é.

# Exemple d’en-tête d’exécution (adapter REGISTRY/namespace/image:tag) export PREFETCH_CONCURRENCY=2 PULL_TIMEOUT_SEC=600 MIN_FREE_GB=20 # pseudo : boucle sur IMAGE_LIST avec xargs -P "$PREFETCH_CONCURRENCY" # timeout "$PULL_TIMEOUT_SEC" docker pull "$img" || exit 3

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é.

Liste blanche sortante (egress) du Mac

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) :

{ "source": "harbor-prefetch", "repository": "namespace/app", "digest": "sha256:…", "status": "failed", "error_code": "pull_timeout", "duration_ms": 612340, "host": "mac-ci-07", "occurred_at": "2026-04-15T12:34:56Z" }

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.

# Sonde passerelle (PORT et jeton à adapter) curl -sS -o /dev/null -w '%{http_code}\n' \ -H 'Authorization: Bearer YOUR_GATEWAY_TOKEN' \ --connect-timeout 3 --max-time 10 \ http://127.0.0.1:PORT/health

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.

Harbor · OpenClaw · Mac distant

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).

Acheter un Mac distant Tarifs Centre d’aide
Apple Silicon
Sortie réseau prévisible
Support 24/7