Scénarios et liste de risques
Les échecs de docker pull transfrontalier suivent des motifs récurrents : limites de débit (HTTP 429), erreurs transitoires amont (502/503), expiration de jeton au milieu du pipeline, pression disque due au cache de couches, enfin TLS, MITM d’entreprise ou proxy HTTP/2 mal négociés sur runners partagés. Avant d’augmenter le parallélisme, identifiez le scénario dominant ; sinon vous optimiserez le mauvais levier.
Sur un parc de Mac distants, les symptômes se confondent : couches qui stagnent, disque sous pression, ou shard registry sur-sollicité. Étiquetez les incidents 429, 5xx, auth ou disque pour ne déplacer qu’une variable par revue hebdomadaire.
max-concurrent-downloads agressif affame les jobs voisins et amplifie la latence SSD — traitez les pulls comme une ressource mutualisée, pas comme un réglage « par développeur ».Si, après hausse du parallélisme, le taux de 429 grimpe, revenez d’un cran et allongez le backoff ; n’ajoutez pas de tentatives sans jitter ni plafond, au risque d’empirer la limitation globale.
Authentification et moindre privilège
GHCR s’appuie en pratique sur un PAT GitHub avec read:packages (classique) ou un jeton fine-grained limité aux dépôts qui publient l’image. Les registries privés (Harbor, offres cloud, distribution auto-hébergée) méritent des comptes robot lecture seule ou des jetons OIDC courts lorsque la plateforme le permet.
Sur hôte Mac distant partagé, évitez un ~/.docker/config.json lisible par le monde avec un PAT long. Préférez un docker login par job via secret injecté, puis docker logout dans un trap, ou un helper d’identifiants lié au trousseau utilisateur CI avec ACL étroites.
Comparez GHCR et registry privé : GitHub couple org, packages et scopes ; Harbor privilégie souvent robots et rétention auditables. Une seule procédure de rotation sur le parc évite les PAT admin personnels qui bloquent l’urgence.
- Ne jamais réutiliser un PAT admin personnel entre équipes : chaque rotation devient incident de production.
- Scoper au plus petit espace de noms ; séparez lecture CI et écriture release.
- Anticiper la rotation bien avant la fin de vie annoncée du fournisseur pour laisser les alertes de dérive agir.
Réseau transfrontalier et tableau comparatif des points de terminaison
Le choix entre ghcr.io et un relai privé combine latence, conformité (résidence des données), coût d’egress et surface opérationnelle — ce n’est pas seulement « le plus rapide ». Servez-vous du tableau pour désigner un endpoint principal et un repli documenté.
| Classe d’endpoint | Forces | Faiblesses | Pertinent quand |
|---|---|---|---|
| GHCR (ghcr.io) | Identité GitHub native, OIDC dans Actions, pas de miroir à opérer vous-même. | Latence inter-régions ; quotas publics partagés sans contrat entreprise. | Images déjà publiées sur GitHub ; runners proches des POP US/EU. |
| Registry privé (même région cloud que le Mac) | Facturation egress prévisible ; SLA régional ; options de lien privé. | Étapes de promotion ou réplication depuis GHCR. | Obligation de résidence géographique proche du parc Mac. |
| Cache pull-through / Harbor proxy | Un cache chaud pour de nombreux jobs ; absorbe les rafales si le disque est dimensionné. | Point unique de défaillance si non clusterisé ; politiques anti-poisoning à écrire. | Nombreux builders partagent les couches ; le lien transfrontalier est cher ou instable. |
Documentez un chemin principal (souvent registry privé régional) et un repli froid (GHCR avec concurrence plus stricte) pour que l’astreinte n’improvise pas pendant une panne amont.
Matrice de paramètres exécutables (valeurs de départ)
Les lignes ci-dessous sont des points de départ pour une CI Mac distante. Mesurez pendant une semaine le taux de 429, le p95 des pulls et la latence disque avant de glisser vers la colonne « agressif ».
| Profil de runner | Couches parallèles (pull) | TTL / rafraîchissement jeton docker login |
Backoff HTTP 429 (s, + jitter) | Backoff HTTP 5xx / connect (s, plafond) | Seuils disque (avertir / ralentir / arrêt) |
|---|---|---|---|---|---|
| Prudent (pool partagé, WAN fragile) | max-concurrent-downloads: 2 · BuildKit parallélisme 2 |
PAT fine-grained 30–60 j ; jeton de job ≤ 6 h ; re-login chaque job | Respecter Retry-After ; sinon 4 → 8 → 16 → 32 → 64 (max 120) |
1 → 3 → 9 → 27 → 60 (max 300) | 80 % / 85 % / 90 % d’utilisation du volume données ; garder ≥ 18 Go libres |
| Équilibré (NVMe, egress stable) | max-concurrent-downloads: 3–4 · BuildKit parallélisme 4 |
PAT 60–90 j avec rotation calendaire à 50 % du TTL ; contrôle hebdo | 2 → 4 → 8 → 16 → 32 (max 90) | 1 → 2 → 6 → 18 → 45 (max 180) | 82 % / 87 % / 92 % ; garder ≥ 25 Go libres |
| Agressif (Mac dédié, miroir même région) | max-concurrent-downloads: 5–6 seulement si la file disque p95 reste plate |
Jeton robot 12–24 h + rafraîchissement automatique à minuit | 1 → 2 → 4 → 8 → 16 (max 60) — acceptable derrière votre cache | 0,5 → 1 → 3 → 9 (max 60) | 85 % / 90 % / 93 % avec docker image prune proactive entre jobs |
Notes d’implémentation : réglez max-concurrent-downloads dans le JSON du daemon Docker ; bornez BuildKit via BUILDKIT_MAX_PARALLELISM=4 (ou équivalent) si votre stack l’expose. Encodez l’échelon de backoff dans un mince wrapper autour de docker pull ou la politique de retry de l’orchestrateur pour éviter qu’équipe par équipe les valeurs divergent.
Pour stabiliser d’autres pulls (build pool, disque), croisez avec FAQ concurrence de pulls & disque.
Intégration CI (exemples avec placeholders)
Adaptez les noms à votre orchestrateur ; les placeholders restent en MAJUSCULES pour un rechercher-remplacer sûr.
- Garde disque :
df -h "$WORKSPACE_ROOT"— code de sortie non nul si le pourcentage utilisé ≥SEUIL_RALENTIissu de la matrice. - Authentification :
echo "$REGISTRY_TOKEN" | docker login HOTE_REGISTRY -u UTILISATEUR_REGISTRY --password-stdin - Pull digest figé :
docker pull HOTE_REGISTRY/ESPACE/IMAGE@sha256:DIGEST_IMAGE - Vérification :
docker image inspect HOTE_REGISTRY/ESPACE/IMAGE@sha256:DIGEST_IMAGE --format '{{.Id}}' - Nettoyage (trap) :
docker logout HOTE_REGISTRYet, si disque >SEUIL_AVERT,docker image prune -f --filter "until=24h"après succès.
Si vous empilez OpenClaw et des guides Docker déjà packagés, enchaînez avec OpenClaw Docker sur Mac distant une fois l’auth registry câblée.
FAQ : tirage bloqué, certificats, proxy
Le pull « gèle » sur une couche. Baissez max-concurrent-downloads, vérifiez MTU et HTTP/2 à travers le proxy d’entreprise, et imposez un timeout « low speed » dans votre wrapper (échec rapide puis retry selon l’échelon 5xx).
Erreurs de certificat. Importez la CA du registry dans le trousseau système et le magasin Docker Desktop ; le nom passé à docker pull doit correspondre au SAN. Les mélanges IP / FQDN provoquent souvent de faux positifs « MITM ».
Chemin proxy. Exportez HTTPS_PROXY de façon cohérente pour daemon et CLI ; liste blanche ghcr.io, *.github.com et votre hôte privé. Si l’auth réussit mais les blobs stagnent, testez les URL de blobs avec curl --http1.1 -I pour détecter une boîte intermédiaire défectueuse.
Synthèse : trancher sur l’endpoint, borner la concurrence, acheter de la capacité prévisible
Choisissez GHCR lorsque l’identité et la publication vivent déjà sur GitHub et que la latence reste acceptable ; basculez vers un registry privé régional ou un cache pull-through lorsque la conformité, la stabilité des rafales ou le coût transfrontalier domine. Associez des jetons moindre privilège à la ligne TTL de la matrice, appliquez les seuils disque avant tout pré-pull, et centralisez le backoff 429/5xx pour éviter les charges en essaim.
Pour disposer d’Apple Silicon dédié où placer caches, daemon JSON et politiques maison, parcourez les pages tarifs et achat, le centre d’aide, puis poursuivez sur le blog technique et l’accueil — accessibles sans connexion.