Public : développeurs et mainteneurs de CI qui exécutent des pipelines Python, données ou ML sur un Mac distant et ont besoin d’installer en masse des wheels et sdist à travers une liaison transfrontalière instable. Mots-clés : Mac distant, uv, miroir PyPI, CI Python, lockfile, tirage parallèle. Entrées utiles : accueil MacPull, liste du blog, stratégie cache Git & npm. La documentation officielle des variables d’environnement uv est sur docs.astral.sh/uv.

① Scène et choix d’outil : pip, uv, conda — quand privilégier uv

Sur un runner macOS partagé, le goulot est souvent le volume HTTP (latence, pertes, proxies) multiplié par des centaines de petits fichiers metadata et quelques archives lourdes. Il faut donc arbitrer entre vitesse de résolution, parallélisme contrôlé, politique de cache et culture de verrouillage des versions.

OutilCas favorablesLimite typique en CI Mac distant
pip Scripts simples, pas de lockfile imposé Peu de leviers natifs sur le parallélisme et le cache unifié ; tirages massifs plus fragiles sur WAN
uv Projets pyproject, uv.lock, ou coexistence avec uv pip pour d’anciens requirements.txt Variables explicites (concurrence, timeouts, retries, cache) et outils de sync figés
conda / mamba Stacks scientifiques hors PyPI, binaires channel Images plus lourdes, gouvernance des miroirs et des channels plus coûteuse

Règle pratique 2026 : si l’essentiel vient de PyPI et que vous voulez des installs reproductibles sur Apple Silicon, commencez par uv. Les équipes déjà stabilisées sur conda pour leurs binaires spécifiques peuvent garder conda pour ces couches et n’utiliser uv que pour les paquets PyPI périphériques, mais évitez deux mondes sans documentation des frontières.

② Matrice de paramètres exécutables : concurrence, timeouts, retries, cache, index

Sur liaison transfrontalière, augmentez d’abord timeouts et retries, puis ajustez la concurrence : trop de flux parallèles sur un proxy saturé déclenche des tempêtes de nouvelles tentatives collectivement pires qu’un débit modéré.

ObjectifVariablePoint de départ indicatif
Téléchargements parallèlesUV_CONCURRENT_DOWNLOADSWAN instable : 4 ; LAN / miroir proche : 816
Timeout lecture HTTP (s)UV_HTTP_TIMEOUT120300 si wheels > quelques centaines de Mo
Timeout connexion TCP (s)UV_HTTP_CONNECT_TIMEOUT3060
Nombre de retries HTTPUV_HTTP_RETRIES58
Répertoire de cache isoléUV_CACHE_DIREx. $HOME/.cache/uv-ci-${CI_PIPELINE_ID:-local}
Index simple par défautUV_DEFAULT_INDEX ou UV_INDEX_URLAmont : https://pypi.org/simple ; remplacez par votre miroir d’org ou géographique
Index supplémentairesUV_INDEX (espaces)Ajoutez l’URL …/simple privée ; croisez avec UV_INDEX_STRATEGY seulement si le risque supply-chain est accepté
# Fragment shell injectable dans un job Mac distant (GitLab CI, Jenkins, Actions self-hosted, etc.) export UV_CONCURRENT_DOWNLOADS=4 export UV_HTTP_TIMEOUT=180 export UV_HTTP_CONNECT_TIMEOUT=45 export UV_HTTP_RETRIES=6 export UV_CACHE_DIR="${HOME}/.cache/uv-ci-${CI_PIPELINE_ID:-local}" export UV_DEFAULT_INDEX="https://pypi.org/simple" # Exemple miroir (à adapter) : export UV_DEFAULT_INDEX="https://pypi.example.corp/simple" # Projet uv : environnement figé uv sync --frozen --no-dev # Flux requirements avec hashes (générer le lock sur une machine de confiance) # uv pip compile pyproject.toml -o requirements.lock --generate-hashes # UV_REQUIRE_HASHES=true uv pip sync requirements.lock

En changeant de miroir, ne réutilisez pas le même UV_CACHE_DIR sans purge : les métadonnées « simple » peuvent ne plus correspondre aux blobs en cache.

③ Réseau transfrontalier : modes d’échec et dépannage (TLS, certificats, proxy)

  • Échec TLS / certificat inconnu : importez la chaîne d’entreprise dans le trousseau macOS ou pointez SSL_CERT_FILE / SSL_CERT_DIR vers un bundle PEM. Selon la version d’uv, testez UV_NATIVE_TLS=true (TLS via le stack système) ou les options documentées équivalentes pour forcer les certificats plateforme.
  • Sortie obligatoire via proxy : HTTPS_PROXY, HTTP_PROXY ; excluez les index internes avec NO_PROXY. Si le proxy ferme les connexions idle plus vite que UV_HTTP_TIMEOUT, réglez d’abord le proxy ou baissez la concurrence.
  • Réinitialisations TCP intermittentes : diminuez UV_CONCURRENT_DOWNLOADS, augmentez UV_HTTP_RETRIES, encapsulez uv sync dans une boucle de retry au niveau orchestrateur avec backoff et jitter.

Pour la même problématique sur Git et images OCI, voir les guides anglais (sans login) : Git & Docker pull acceleration et Remote Mac cache strategy: Git & npm CI, ainsi que le miroir Git / npm / Homebrew transfrontalier sur la version française.

④ Cohérence pyproject / requirements.lock et étapes CI reproductibles

Liste courte — projet uv
  • Exécutez uv lock lors des changements de dépendances et versionnez uv.lock.
  • En CI : uv sync --frozen (ou --locked selon votre politique) pour interdire toute réécriture silencieuse du lock pendant le job.
  • Flux requirements.txt : générez requirements.lock avec uv pip compile … --generate-hashes ; en installation, uv pip sync requirements.lock et UV_REQUIRE_HASHES si le fichier impose des hashes.
  • Clé de cache CI : commit + hash de uv.lock + hôte de UV_DEFAULT_INDEX + version mineure de Python.
# Vérifier que le lock reflète pyproject (sortie non nulle = échec volontaire) uv lock --check # Chemin principal d’installation en CI uv sync --frozen --no-dev

Une merge request qui modifie des dépendances sans mettre à jour le lock doit faire échouer le pipeline tôt : le Mac distant ne doit pas passer dix minutes à télécharger avant d’apprendre que la résolution ne correspond plus au dépôt.

⑤ FAQ : pollution de cache, wheels plateforme, index privé

Cache : un répertoire partagé entre jobs concurrents sans convention, ou la réutilisation du même cache après bascule de miroir, produit des métadonnées incohérentes. Préfixez par identifiant de pipeline ou de tenant et planifiez uv cache prune dans une fenêtre de maintenance.

Wheels et architecture : un lock généré sur x86_64 ne garantit pas les mêmes artefacts sur arm64 Apple Silicon. Fixez UV_PYTHON au même chemin qu’en production ou générez le lock sur un runner représentatif.

Index multiples : tenez UV_DEFAULT_INDEX pour la voie principale et ajoutez l’index privé via UV_INDEX. Toute stratégie « meilleure correspondance » entre index doit être explicitement approuvée en revue de sécurité.

En résumé : sur Mac distant, stabilisez d’abord timeouts et retries, puis réglez la concurrence ; isolez UV_CACHE_DIR ; figez les dépendances avec uv lock et uv sync --frozen. Pour monter un runner homogène Apple Silicon avec bande passante prévisible, parcourez les pages sans connexion obligatoire : tarifs, achat, centre d’aide. Approfondissement en anglais : accélération Git & Docker.

Python & ML sur Mac distant

Même stack locale, même wheel — côté CI

MacPull propose des nœuds Mac mini cloud pour exécuter vos installs uv proches de vos utilisateurs finaux. Comparez les forfaits, lisez l’aide et enchaînez avec les guides anglais sur les tirages Git / Docker — le tout accessible sans compte.

Tarifs Acheter Centre d’aide Article EN cache Git/npm
Apple Silicon
Sortie réseau stable
Support 24/7