Introduction
Docker Hub est le registre public par défaut pour les images Docker. La plupart des équipes commencent à l'utiliser sans trop réfléchir à la configuration. Cela fonctionne jusqu'à ce qu'un tirage échoue en CI, qu'une image poussée n'ait pas la bonne étiquette, ou qu'un service qui fonctionnait sur un portable ne puisse pas s'authentifier depuis un serveur de production. Ces échecs sont presque toujours causés par une petite erreur de configuration invisible jusqu'au moment où elle bloque une version.
Cet article passe en revue les erreurs de configuration Docker Hub les plus courantes, comment les reproduire de manière contrôlée, à quoi ressemble l'échec et comment récupérer sans deviner. Il s'adresse aux développeurs, aux ingénieurs DevOps et aux petites équipes techniques qui gèrent leurs propres pipelines de construction et de déploiement de conteneurs. Chaque section donne des commandes concrètes, des sorties attendues et un chemin de retour en arrière afin que vous puissiez pratiquer l'échec avant qu'il ne se produise en production.
L'objectif est la sécurité opérationnelle. Observez d'abord, modifiez un seul élément ciblé, vérifiez le résultat et sachez comment revenir à un état connu et fonctionnel. Utilisez des espaces réservés pour les secrets, gardez les modifications petites et documentez ce que signifie « ça marche » avant de commencer.
Inventaire des versions et de l'environnement
Avant de modifier toute configuration Docker Hub, enregistrez l'environnement exact. Docker Hub lui-même n'a pas de version que vous installez, mais le moteur Docker, Docker Compose et l'interface CLI de Docker ont tous des versions qui affectent l'authentification, les limites de débit et la gestion des manifestes. Une inadéquation ici peut faire paraître cassée une configuration valide.
Commencez par des commandes en lecture seule. Identifiez les versions installées et le contexte Docker actuel :
docker version
La sortie attendue comporte deux blocs, un pour le client et un pour le serveur (si le démon est en cours d'exécution). Notez la version de l'API et les lignes OS/Arch. Sur une machine avec Docker 24.0.7, le bloc client ressemble à :
Client: Docker Engine - Community
Version: 24.0.7
API version: 1.43
Go version: go1.21.5
Git commit: afdd53b
Built: Wed Dec 13 19:26:58 2023
OS/Arch: linux/amd64
Context: default
Si le serveur ne fonctionne pas, la commande imprime le bloc client puis une erreur telle que Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. C'est un signal que le problème est local, pas dans la configuration de Docker Hub.
Pour les projets Compose, vérifiez la version de Compose séparément :
docker compose version
La sortie ressemble à Docker Compose version v2.23.3. Le plugin v2 est le seul chemin pris en charge pour la syntaxe de commande docker compose utilisée tout au long de cet article. Si vous voyez docker-compose avec un trait d'union, vous êtes sur l'ancienne version autonome et vous devriez migrer avant d'attendre un comportement Compose moderne.
Un inventaire d'environnement pratique inclut également une liste des conteneurs en cours d'exécution. Utilisez un format qui montre les noms, l'état et les ports en un coup d'œil :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Pour une configuration saine à un seul conteneur, la sortie pourrait être :
NAMES STATUS PORTS
web_app_1 Up 2 hours 0.0.0.0:8080->80/tcp
Si un conteneur qui devrait fonctionner n'est pas dans cette liste, l'erreur de configuration peut être dans la politique de redémarrage ou la définition du service, pas dans les identifiants Docker Hub.
Erreurs courantes de configuration Docker Hub
La plupart des problèmes Docker Hub proviennent d'une courte liste de mauvaises configurations. Reconnaître le schéma tôt fait gagner du temps. Les sections suivantes détailleront chaque erreur avec une reproduction concrète et un chemin de récupération. Les erreurs les plus fréquentes sont :
- Utiliser les mauvais identifiants ou aucun. Docker Hub exige une authentification pour les dépôts privés et pour éviter les limites de débit anonymes. Une faute de frappe dans le nom d'utilisateur, l'utilisation d'un jeton d'accès expiré ou l'oubli de se connecter sur une nouvelle machine causent tous des erreurs
unauthorized: incorrect username or password. - Pousser vers un nom de dépôt qui n'existe pas ou que vous ne possédez pas. Les espaces de noms Docker Hub sont globaux. Si vous poussez
myappsans préfixe d'utilisateur ou d'organisation, Docker peut l'interpréter commelibrary/myappet échouer. L'étiquette doit inclure un espace de noms que vous contrôlez, commemyusername/myapp:latest. - Oublier d'étiqueter l'image avant de pousser.
docker push myusername/myappéchoue si l'image locale n'a pas cette étiquette exacte. L'image doit d'abord être étiquetée avec le nom complet du dépôt. - Épuisement des limites de débit dû aux tirages anonymes. Docker Hub applique des limites de tirage basées sur l'IP et le type de compte. Les utilisateurs anonymes ont un nombre limité de tirages par six heures. Lorsque la limite est atteinte, les tirages échouent avec
toomanyrequests: You have reached your pull rate limit. - Coder en dur les identifiants Docker Hub dans les scripts ou les variables d'environnement qui fuient dans les journaux ou les fichiers partagés. C'est une erreur de sécurité qui peut exposer votre compte. La meilleure pratique est d'utiliser des assistants d'identification Docker ou des intégrations de gestion des secrets.
Chacune de ces erreurs est récupérable, mais le chemin de récupération est différent. Les sections suivantes montrent exactement comment les diagnostiquer et les corriger.
Chemin de configuration sûr
Lorsque vous modifiez les paramètres Docker Hub, séparez ce que vous observez de ce que vous changez. Commencez par vérifier si l'authentification fonctionne. Une vérification en lecture seule est :
docker login
Cela demande un nom d'utilisateur et un mot de passe (ou un jeton d'accès). Tant que vous n'exécutez pas cette commande, la CLI Docker peut ne pas être authentifiée. La sortie en cas de succès est Login Succeeded. La commande stocke les identifiants dans ~/.docker/config.json par défaut. Ce fichier contient désormais un jeton d'authentification encodé en base64. Sur un système multi-utilisateurs, assurez-vous que les permissions du fichier sont 600 :
ls -l ~/.docker/config.json
La sortie doit afficher -rw------- 1 user user .... Si le fichier est lisible par tous, n'importe quel utilisateur de l'hôte peut voler les identifiants.
Une alternative plus sûre pour les serveurs de production est d'éviter de stocker les identifiants sur le disque. Utilisez un assistant d'identification tel que docker-credential-pass ou fiez-vous aux variables d'environnement en CI. Pour les systèmes CI, définissez DOCKER_USERNAME et DOCKER_PASSWORD comme variables protégées et connectez-vous avec :
echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
La commande lit le mot de passe depuis l'entrée standard, ce qui évite de l'exposer dans la liste des processus ou l'historique du shell. Dans GitHub Actions, cela ressemble à :
- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin
Après la connexion, le chemin de configuration sûr consiste à étiqueter une image et à la pousser vers votre propre espace de noms. Un exemple minimal :
docker tag my-local-image:latest myusername/myapp:1.0.0
docker push myusername/myapp:1.0.0
La sortie attendue pour la poussée se termine par une ligne de résumé et de taille, telle que :
1.0.0: digest: sha256:9c7a... size: 1578
Si l'espace de noms myusername n'existe pas sur Docker Hub, ou si vous n'êtes pas connecté en tant que cet utilisateur, la poussée échoue avec denied: requested access to the resource is denied. C'est le signal pour corriger l'authentification ou la propriété de l'espace de noms avant de continuer.
Vérification et diagnostics
Après tout changement de configuration, vérifiez le résultat avec une commande séparée en lecture seule. Ne supposez pas que la dernière poussée a réussi simplement parce que la commande s'est terminée avec le code 0. Vérifiez le manifeste réel sur Docker Hub en utilisant docker manifest inspect. Cela fonctionne même si vous n'êtes pas connecté, en supposant que le dépôt est public :
docker manifest inspect myusername/myapp:1.0.0
Une sortie réussie est un JSON avec la version du schéma, le type de média et une liste de couches. Une étiquette manquante donne no such manifest: docker.io/myusername/myapp:1.0.0.
Pour les dépôts privés, vous devez être connecté. Une inspection de manifeste non authentifiée d'un dépôt privé renvoie unauthorized: authentication required.
Les diagnostics pour les échecs de tirage sont similaires. Si un docker pull échoue avec toomanyrequests, vérifiez l'état de votre limite de débit. Les en-têtes de réponse du registre incluent des informations sur la limite de débit. Comme la CLI Docker n'affiche pas les en-têtes par défaut, utilisez curl pour les voir :
curl -I https://registry-1.docker.io/v2/
Recherchez les en-têtes RateLimit-Limit et RateLimit-Remaining. Pour les requêtes anonymes, les valeurs typiques pourraient être :
RateLimit-Limit: 100;w=21600
RateLimit-Remaining: 97;w=21600
Cela indique 100 tirages par 6 heures, avec 97 restants. Si RateLimit-Remaining est 0, vous avez épuisé la limite anonyme et devez soit vous authentifier (ce qui augmente la limite), soit attendre que la fenêtre se réinitialise.
Un autre diagnostic pour les erreurs de configuration est d'inspecter la propre configuration du démon Docker. Les miroirs de registre et les registres non sécurisés sont définis dans /etc/docker/daemon.json. Un miroir mal configuré peut faire échouer les tirages avec dial tcp: lookup mirror.example.com: no such host. Vérifiez le fichier avec :
cat /etc/docker/daemon.json
Un fichier minimal correct pour un miroir pourrait être :
{
"registry-mirrors": ["https://mirror.example.com"]
}
Si vous modifiez ce fichier, redémarrez le démon Docker et vérifiez que le miroir est actif avec docker info, qui liste le miroir configuré sous Registry Mirrors.
Modes d'échec et récupération
Chaque erreur de configuration a une signature d'échec. Voici les plus courantes et leurs étapes de récupération.
Échec : docker pull donne unauthorized: incorrect username or password
Cela se produit lorsque le démon n'a pas d'identifiants pour Docker Hub. Par exemple, un serveur nouvellement provisionné exécute docker pull myusername/myapp:latest et obtient cette erreur parce qu'aucune docker login n'a été effectuée.
Récupération : Connectez-vous avec des identifiants valides. Si le nom d'utilisateur ou le mot de passe est incorrect, générez un nouveau jeton d'accès depuis Docker Hub et reconnectez-vous. Vérifiez la connexion en tirant une petite image publique :
docker login
docker pull hello-world
Si hello-world se tire avec succès, l'authentification fonctionne. Réessayez ensuite le tirage de l'image privée.
Échec : docker push échoue avec denied: requested access to the resource is denied
C'est presque toujours une inadéquation d'espace de noms. Vous êtes connecté en tant que john, mais l'étiquette de l'image est jane/myapp:latest, et vous n'avez pas d'accès en écriture à l'espace de noms de Jane.
Récupération : Réétiquetez l'image sous votre propre espace de noms et poussez à nouveau.
docker tag myapp:latest john/myapp:latest
docker push john/myapp:latest
La poussée réussit si john possède cet espace de noms. Si vous devez pousser vers une organisation, vérifiez que votre compte a un accès en écriture d'équipe dans les paramètres de l'organisation Docker Hub.
Échec : la poussée réussit mais la mauvaise étiquette est poussée
Exemple : un pipeline CI étiquette une image comme latest et écrase une étiquette dont dépend la production. Le prochain déploiement tire une version non testée.
Récupération : Utilisez des étiquettes de version sémantique immuables pour les déploiements de production. Modifiez le pipeline pour étiqueter avec le SHA du commit git et une étiquette semver :
docker tag myapp:latest myusername/myapp:1.2.3
docker tag myapp:latest myusername/myapp:git-$(git rev-parse --short HEAD)
docker push myusername/myapp:1.2.3
docker push myusername/myapp:git-$(git rev-parse --short HEAD)
Le déploiement de production référence 1.2.3, pas latest. Cela évite les écrasements accidentels et rend le retour en arrière simple.
Échec : limite de débit dépassée pendant les builds CI
Les tirages anonymes dans un serveur CI occupé atteignent la limite en plein build. L'erreur est :
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Récupération : Ajoutez un identifiant Docker Hub à l'environnement CI et connectez-vous au début du travail. Dans GitHub Actions, utilisez docker/login-action avec un jeton d'accès personnel. Dans d'autres CI, utilisez l'approche docker login --password-stdin montrée précédemment. Les comptes authentifiés obtiennent une limite de débit plus élevée (par exemple, 200 tirages par 6 heures pour les comptes gratuits, plus pour les plans payants).
Si vous ne pouvez pas vous connecter, envisagez d'utiliser un cache intermédiaire ou de vous inscrire à un plan payant. Mais la correction la plus directe est l'authentification.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle avant et après avoir modifié la configuration Docker Hub dans un environnement partagé. Attribuez un responsable à chaque élément ; pour les équipes, le responsable peut être un rôle, mais une personne doit vérifier l'achèvement. Revisitez la liste de contrôle à chaque sprint ou après tout incident impliquant l'accès au registre.
| # | Tâche | Responsable | Commande ou signal de vérification | Fréquence |
|---|---|---|---|---|
| 1 | Enregistrer les versions du client et du serveur Docker | Priya Shah, responsable ingénierie | La sortie de docker version correspond à la plage attendue | Au début du changement |
| 2 | Confirmer l'état d'authentification sur l'hôte | Alex Torres, ingénieur DevOps | docker login réussit sans invite | Avant tout travail de poussée/tirage |
| 3 | Étiqueter toutes les images avec l'espace de noms complet et la version sémantique | Équipe (revue de code) | docker images montre des étiquettes comme org/app:1.2.3 | Chaque build |
| 4 | Éviter les tirages anonymes en CI | Alex Torres, ingénieur DevOps | Les journaux du travail CI montrent Login Succeeded avant les tirages | Chaque exécution CI |
| 5 | Protéger les permissions du fichier d'identifiants Docker | Priya Shah, responsable ingénierie | ls -l ~/.docker/config.json montre 600 | Audit mensuel |
| 6 | Vérifier que le manifeste poussé existe et est correct | Équipe (responsable de version) | docker manifest inspect org/app:1.2.3 renvoie du JSON | Avant la version |
| 7 | Maintenir une politique d'étiquette de retour en arrière d'urgence | Alex Torres, ingénieur DevOps | L'étiquette de version précédente existe toujours | Revue trimestrielle |
Cette liste de contrôle crée un schéma de vérification reproductible. Chaque élément est suffisamment concret pour qu'un nouveau membre de l'équipe puisse l'exécuter sans contexte préalable. La colonne du responsable est intentionnellement spécifique ; quand quelque chose échoue, il est clair à qui demander.
Pièges courants et comment les éviter
Au-delà des erreurs spécifiques déjà couvertes, plusieurs pièges plus subtils font souvent dérailler la configuration Docker Hub.
Identifiants en texte clair
De nombreux tutoriels montrent docker login -u username -p password. Cette commande écrit le mot de passe dans l'historique du shell et les listes de processus. Tout utilisateur ayant accès à l'hôte ou aux journaux CI peut le récupérer.
Évitez-le : Utilisez toujours --password-stdin pour les scripts, ou exécutez docker login de manière interactive. En CI, utilisez des variables d'environnement protégées et évitez de faire écho aux secrets.
Ignorer les règles d'espace de noms Docker Hub
Les noms d'espace de noms Docker Hub sont en minuscules, doivent commencer par une lettre ou un chiffre, et peuvent inclure des tirets. De nombreuses équipes essaient de pousser vers un dépôt avec des lettres majuscules dans l'espace de noms ou un soulignement, et la poussée échoue avec une erreur déroutante sur la dénomination du dépôt.
Évitez-le : Standardisez un espace de noms en minuscules, séparé par des tirets, par équipe. Par exemple, utilisez frontend-team et non Frontend_Team. Documentez le mappage de l'espace de noms dans le README du dépôt.
Écraser l'étiquette latest
L'étiquette latest est pratique mais dangereuse. Un schéma courant est qu'un pipeline de build pousse latest à chaque commit sur main. Les conteneurs de production pointent alors vers latest, et un mauvais commit provoque une panne sans retour en arrière facile vers une image connue et fonctionnelle.
Évitez-le : Utilisez des étiquettes immuables comme le SHA git pour le développement et des versions sémantiques pour les versions. Si vous devez utiliser latest, traitez-le comme un pointeur mobile et ne le tirez jamais en production. Un retour en arrière signifie alors changer le manifeste de déploiement pour référencer une étiquette semver précédente.
Oublier de se déconnecter sur les machines partagées
Laisser des identifiants sur un serveur de build partagé permet à quiconque de pousser vers vos dépôts. Lorsque vous avez terminé, exécutez docker logout pour supprimer les identifiants stockés.
Évitez-le : Incluez docker logout dans les étapes de nettoyage CI si les identifiants sont stockés dans le fichier de configuration Docker. Mieux encore, utilisez des assistants d'identification qui s'intègrent au magasin de secrets de l'hôte, afin qu'aucun jeton en texte clair ne soit laissé derrière.
Conclusion
Les erreurs de configuration Docker Hub sont courantes, mais elles sont toutes découvrables avec les bonnes commandes d'observation. Les problèmes les plus fréquents sont les échecs d'authentification, les erreurs d'espace de noms, les limites de débit et la confusion des étiquettes mutables. Chacun a un message d'erreur signature et un chemin de récupération simple si vous savez quoi chercher.
Commencez par un inventaire en lecture seule : docker version, docker ps et docker info. Avant tout changement, vérifiez l'authentification avec docker login. Lors de la poussée, utilisez toujours un espace de noms complet et une étiquette spécifique. Vérifiez avec docker manifest inspect et vérifiez les en-têtes de limite de débit avec curl. Si quelque chose échoue, cherchez la chaîne d'erreur exacte et faites-la correspondre à l'un des modes d'échec de cet article.
Un flux de travail Docker Hub fiable rend les échecs visibles, protège les identifiants, limite les changements au dépôt et à l'étiquette prévus, et définit un chemin de retour en arrière avant qu'un incident ne force la décision. Pratiquez les étapes de retour en arrière sur un espace de noms non productif avant d'en avoir besoin en cas d'urgence.