30 - Registries et stratégie de tags
Ce que tu vas apprendre
- Les registries principaux : Docker Hub, GHCR, self-hosted
- Comment push et pull des images
- La convention de nommage des images
- Pourquoi
latestte causera des problèmes - Une stratégie de tags qui marche en prod
Prerequisites
- Savoir construire une image Docker
- Avoir un compte Docker Hub ou GitHub
J'ai déployé en production une image taguee latest. Le mardi, tout marchait. Le mercredi, l'API renvoyait des erreurs 500. Personne n'avait touche au serveur. Mais quelqu'un avait push une nouvelle version sur latest et le serveur avait fait un docker pull automatique.
Meme image, meme tag, contenu différent. C'est le piège fondamental de latest.
La convention de nommage
Une image Docker a un nom complet qui suit ce format :
registry/namespace/image:tag
Exemples concrets :
docker.io/library/node:20-slim # Docker Hub, image officielle
docker.io/monuser/mon-app:1.2.3 # Docker Hub, image perso
ghcr.io/monorg/mon-app:sha-a1b2c3d # GitHub Container Registry
registry.gitlab.com/monorg/mon-app:main # GitLab Registry
localhost:5000/mon-app:dev # Registry local
Quand tu ecris node:20-slim, Docker ajoute implicitement docker.io/library/. C'est un raccourci, pas de la magie.
Docker Hub
Le registry par défaut. Chaque docker pull sans prefixe va chercher sur Docker Hub.
bash# Se connecter
docker login
# Taguer une image locale
docker tag mon-app:latest monuser/mon-app:1.0.0
# Pousser
docker push monuser/mon-app:1.0.0
# Tirer
docker pull monuser/mon-app:1.0.0
Docker Hub offre un repo prive gratuit. Au-dela, c'est payant. Les images publiques sont illimitees.
Les limites a connaître : 100 pulls par 6 heures pour les utilisateurs anonymes, 200 pour les utilisateurs authentifies. En CI, ca peut bloquer vite si tu as beaucoup de jobs parallèles.
GitHub Container Registry (GHCR)
GHCR est intégré a GitHub. Les images sont liees a un compte ou une organisation. Les permissions suivent celles du repo.
bash# Se connecter avec un token GitHub
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# Taguer et pousser
docker tag mon-app:latest ghcr.io/monorg/mon-app:1.0.0
docker push ghcr.io/monorg/mon-app:1.0.0
L'avantage de GHCR : pas de rate limiting pour les images publiques, intégration native avec GitHub Actions, et les images apparaissent dans l'onglet "Packages" du repo.
C'est ce que j'utilise pour tous mes projets sur GitHub, y compris sur paltemps.fr. Le workflow est simple : GitHub Actions build l'image et la push sur GHCR. Le serveur de prod pull depuis GHCR.
Registry self-hosted
Pour les entreprises qui veulent garder leurs images en interne, Docker propose un registry open source :
yamlservices:
registry:
image: registry:2
ports:
- "5000:5000"
volumes:
- registry-data:/var/lib/registry
volumes:
registry-data:
bashdocker tag mon-app:latest localhost:5000/mon-app:1.0.0
docker push localhost:5000/mon-app:1.0.0
C'est minimaliste. Pas d'interface web, pas de gestion d'utilisateurs, pas de scanning de vulnérabilités. Pour un vrai registry prive, regarde Harbor ou les offres managees (AWS ECR, Google Artifact Registry, Azure Container Registry).
Le piège de latest
latest n'est pas un tag special pour Docker. C'est juste un tag par défaut. Quand tu fais docker build -t mon-app . sans spécifier de tag, Docker ajoute :latest. Quand tu fais docker pull mon-app sans tag, Docker cherche :latest.
Le problème : latest est mutable. Chaque nouveau push ecrase le précédent. Tu ne sais jamais quelle version se cache derrière.
bash# Lundi : mon-app:latest = version 1.2.3
docker push mon-app:latest
# Mardi : mon-app:latest = version 1.3.0
docker push mon-app:latest
Si ton serveur de prod fait un docker pull mon-app:latest, il recoit une version différente selon le jour. C'est une source de bugs impossibles a diagnostiquer.
Ma regle : latest en dev pour tester vite, jamais en staging ni en prod.
Une stratégie de tags qui marche
Voici ce que j'utilise et que je recommande :
Semver pour les releases : 1.0.0, 1.0.1, 1.1.0. Immutable. Une version = un contenu.
Git SHA pour la traçabilité : sha-a1b2c3d. Tu sais exactement quel commit a produit l'image. Utile pour le debug.
Branche pour le staging : main, develop. Mutable, mais c'est attendu. Le staging suit la branche.
En pratique, chaque build produit plusieurs tags :
bash# Un build, plusieurs tags
docker tag mon-app:latest ghcr.io/monorg/mon-app:1.2.3
docker tag mon-app:latest ghcr.io/monorg/mon-app:sha-a1b2c3d
docker tag mon-app:latest ghcr.io/monorg/mon-app:main
docker push ghcr.io/monorg/mon-app:1.2.3
docker push ghcr.io/monorg/mon-app:sha-a1b2c3d
docker push ghcr.io/monorg/mon-app:main
En prod, on deploie avec le tag semver. Si ca casse, on sait quelle version c'est, et on peut rollback vers la précédente.
Automated builds
La plupart des registries supportent les builds automatiques à partir d'un repo Git. Mais la méthode moderne est de builder dans la CI et de push le résultat.
L'avantage : tu contrôles le build. Tu peux lancer les tests avant de push. Tu peux signer l'image. Tu decides quand une image merite d'etre publiee.
On détaillé ca dans l'article sur la CI/CD.
Résumé
- Le nom complet d'une image suit le format
registry/namespace/image:tag - Docker Hub est le défaut, GHCR est mieux intégré a GitHub
latestest mutable et dangereux en production : utilise des tags semver- Combine semver + git SHA + branche pour couvrir tous les cas
- Pense au nettoyage des vieilles images dans ton registry
Precedent : 29 - Nettoyage | Suivant : 31 - CI/CD