Registry Docker GitLab : créer, publier et automatiser ses images en CI/CD

DOCKER · GITLAB · CI/CD · DEVOPS

Je t’explique comment j’utilise la registry Docker GitLab pour stocker et distribuer mes images en toute confidentialité, sans dépendre de Docker Hub, gratuitement, avec un pipeline CI/CD qui build et push automatiquement à chaque commit.

Registry Docker GitLab : publier une image Docker via pipeline CI/CD GitLab avec build automatique
Publier une image Docker sur la registry GitLab via pipeline CI/CD : build automatique a chaque commit.

Quand j’ai commencé à construire des images Docker pour mes projets clients, ma première réaction a été de pousser tout sur Docker Hub. Rapide, connu, universel. Mais ça ne tient pas longtemps en production : les images privées sont payantes au-delà d’une certaine limite, la visibilité par défaut est publique si on n’y fait pas attention, et Docker Hub a connu plusieurs incidents notables ces dernières années.

J’utilise GitLab pour mes repos, et GitLab embarque une registry Docker complète, gratuite, intégrée au CI/CD. Autant en profiter. Dans cet article, je te montre comment je procède de A à Z : création du repo, Dockerfile, commandes de build et push, pipeline automatique, et gestion des accès.

💡

Réponse rapide

Pour publier une image Docker sur la registry GitLab : docker build -t registry.gitlab.com/[group]/[repo]/[image]:[tag] . puis docker push. En CI/CD, les variables CI_REGISTRY, CI_REGISTRY_USER et CI_REGISTRY_PASSWORD sont injectées automatiquement.

Pourquoi utiliser la registry GitLab plutôt que Docker Hub

Docker Hub reste la référence pour les images publiques officielles (Nginx, PostgreSQL, Node.js…). Mais pour tes propres images, les limites arrivent vite :

⚠ Images privées limitées sur Docker Hub Free

Le plan gratuit Docker Hub ne propose qu’un seul repo privé. Dès que tu as plusieurs projets, tu paies ou tu t’organises autrement.

⚠ Rate limiting sur les pulls anonymes

Docker Hub limite les pulls depuis des IPs non authentifiées à 100/6h. Sur un CI/CD ou un cluster, c’est rapidement bloquant.

🔴 Incident Docker Hub 2023

Docker Hub a supprimé des repos gratuits inactifs et rendu publics temporairement des repos privés lors d’une migration, un signal fort pour ne pas dépendre d’un seul service tiers.

La registry GitLab, c’est quoi ? C’est une registry Docker OCI-compatible intégrée directement dans chaque projet GitLab. Gratuite sur gitlab.com (dans les limites de stockage du compte), sans restriction de repos privés, et connectée nativement au CI/CD. Mes images restent dans le même endroit que mon code.

🔒

Privé par défaut

Tes images suivent la visibilité de ton projet GitLab. Pas d’accès public accidentel.

🆓

Gratuit sur gitlab.com

Repos privés illimités, registry incluse dans le plan Free (5 Go de stockage).

Intégration CI/CD native

Variables d’authentification injectées automatiquement dans chaque job, pas besoin de gérer des secrets manuellement.

🏗️

Self-hosted possible

Si tu héberges ta propre instance GitLab, ta registry tourne sur ta propre infra. Zéro dépendance externe.

Prérequis

✅ Ce qu’il te faut avant de commencer


Un compte GitLab (gitlab.com gratuit suffit)

Docker installé sur ton poste (docker --version doit répondre)

Git configuré localement (git config --global user.email)

Un Personal Access Token GitLab avec le scope read_registry / write_registry pour les push manuels

Créer un repo GitLab avec la registry activée

Sur gitlab.com, crée un nouveau projet : New project > Create blank project. Donne-lui un nom (ex: mon-app), choisis le niveau de visibilité (Private pour les projets clients), et valide.

La registry Docker est activée par défaut sur chaque projet. Tu peux la trouver dans le menu latéral : Deploy > Container Registry. L’URL de ta registry suivra ce format :

registry.gitlab.com/[namespace]/[projet]

Par exemple, si ton namespace GitLab est mon-groupe et ton projet mon-app :

registry.gitlab.com/mon-groupe/mon-app
💡

Si la registry n’apparaît pas

Dans Settings > General > Visibility, project features, permissions, vérifie que Container Registry est activé. Sur une instance GitLab self-hosted, l’admin doit activer la registry au niveau de l’instance.

Écrire un Dockerfile minimal

Pour l’exemple, je pars sur une application Node.js simple. Le principe est identique pour Python, Go, PHP ou n’importe quel runtime.

# Dockerfile
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

USER node

CMD ["node", "server.js"]

Bonnes pratiques Dockerfile

J’utilise systématiquement alpine pour réduire la surface d’attaque, USER node pour ne pas tourner en root, et npm ci --only=production pour éviter les dépendances de dev dans l’image finale.

Ajoute aussi un fichier .dockerignore pour ne pas copier les fichiers inutiles :

.git
node_modules
.env
*.md
tests/
coverage/

Build, tag et push vers registry.gitlab.com

La séquence est toujours la même : build, tag avec l’URL complète de la registry, login, push.

1. Authentification sur la registry

docker login registry.gitlab.com

GitLab te demande ton nom d’utilisateur et un token. N’utilise pas ton mot de passe GitLab – crée un Personal Access Token (Settings > Access Tokens) avec le scope write_registry.

⚠️

Ne jamais utiliser ton mot de passe GitLab

Pour la registry, crée toujours un Personal Access Token ou un Deploy Token avec uniquement les scopes nécessaires. Le mot de passe principal ne doit jamais transiter dans des scripts ou des commandes shell.

2. Build de l’image avec le bon tag

docker build -t registry.gitlab.com/mon-groupe/mon-app:1.0.0 .

Je taggue toujours avec un numéro de version explicite. En plus, j’ajoute souvent :latest pour simplifier les déploiements :

docker build -t registry.gitlab.com/mon-groupe/mon-app:1.0.0 \
             -t registry.gitlab.com/mon-groupe/mon-app:latest .

3. Push vers la registry GitLab

docker push registry.gitlab.com/mon-groupe/mon-app:1.0.0
docker push registry.gitlab.com/mon-groupe/mon-app:latest

Une fois poussée, tu retrouves l’image dans l’interface GitLab sous Deploy > Container Registry. Tu peux vérifier les layers, les tags, la date de push et la taille de chaque image.

Automatiser avec .gitlab-ci.yml

Le vrai gain de la registry GitLab, c’est l’intégration CI/CD. À chaque commit, le pipeline build l’image et la pousse automatiquement, sans que tu aies à gérer les credentials manuellement, car GitLab injecte les variables nécessaires dans chaque job.

# .gitlab-ci.yml
stages:
  - build

variables:
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  IMAGE_LATEST: $CI_REGISTRY_IMAGE:latest

docker-build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_TAG -t $IMAGE_LATEST .
    - docker push $IMAGE_TAG
    - docker push $IMAGE_LATEST
  only:
    - main
    - tags
💡

Variables CI_REGISTRY_* : injectées automatiquement

CI_REGISTRY = URL de la registry du projet, CI_REGISTRY_USER = utilisateur de build, CI_REGISTRY_PASSWORD = token temporaire valide pour ce job. Ces trois variables sont disponibles dans tous les pipelines GitLab sans aucune configuration supplémentaire.

Optimiser avec le cache des layers

Pour accélérer les builds sur le CI, j’utilise le cache de layers Docker via BuildKit :

docker-build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
    DOCKER_BUILDKIT: "1"
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - |
      docker build \
        --cache-from $CI_REGISTRY_IMAGE:latest \
        --build-arg BUILDKIT_INLINE_CACHE=1 \
        -t $IMAGE_TAG \
        -t $IMAGE_LATEST \
        .
    - docker push $IMAGE_TAG
    - docker push $IMAGE_LATEST
  only:
    - main
    - tags

Utiliser l’image dans FROM, docker-compose et CI

Dans un Dockerfile (FROM)

Pour construire une image qui hérite de ton image privée :

FROM registry.gitlab.com/mon-groupe/mon-app:1.0.0

# ... instructions supplémentaires
COPY config/ /app/config/

Dans un docker-compose.yml

version: "3.9"

services:
  app:
    image: registry.gitlab.com/mon-groupe/mon-app:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
    env_file:
      - .env

Sur le serveur de déploiement, tu devras te connecter à la registry avant de faire le docker compose pull :

docker login registry.gitlab.com -u [user] -p [token]
docker compose pull
docker compose up -d

Dans un autre pipeline GitLab

Si tu veux utiliser l’image d’un projet A dans le pipeline d’un projet B, tu peux utiliser un Deploy Token avec uniquement le scope read_registry :

# .gitlab-ci.yml du projet B
deploy:
  stage: deploy
  before_script:
    - docker login registry.gitlab.com -u $DEPLOY_TOKEN_USER -p $DEPLOY_TOKEN_PASS
  script:
    - docker pull registry.gitlab.com/mon-groupe/mon-app:latest
    - docker compose up -d

Conseil infogérance Linux-Man

J’utilise systématiquement des Deploy Tokens par projet client plutôt que des Personal Access Tokens. Ainsi, si un token est compromis, l’impact est limité au seul projet concerné, pas à l’ensemble du compte GitLab. Tu peux créer autant de Deploy Tokens que nécessaire dans Settings > Repository > Deploy tokens. Si tu veux déléguer la gestion des serveurs à une équipe externe, je propose un accompagnement dédié – contacte-moi.

Gestion des tokens et des accès

C’est souvent la partie qu’on bâcle au début et qu’on regrette plus tard. Voici comment je structure les accès selon les cas d’usage :

🔑 Personal Access Token (PAT)

Usage : push manuel depuis ton poste développeur. Scopes nécessaires : read_registry + write_registry. Crée-le dans User Settings > Access Tokens. Stocke-le dans ton keychain local, jamais en clair dans un script.

🚀 Variables CI/CD GitLab (CI_REGISTRY_*)

Usage : pipelines du projet lui-même. Variables injectées automatiquement par GitLab, aucune configuration nécessaire. Ces tokens sont éphémères (valables pour la durée du job uniquement).

🏭 Deploy Token

Usage : pull depuis un serveur de production, depuis un autre projet CI, ou depuis une application externe. Crée-le dans Settings > Repository > Deploy tokens. Scope read_registry uniquement si c’est juste pour pull. Stocke-le en variable CI/CD protégée ou dans un vault (HashiCorp Vault, Ansible Vault).

👥 Group-level access token

Usage : accès à plusieurs projets du même groupe. Pratique pour un pipeline de déploiement centralisé qui tire des images de plusieurs projets. Nécessite un plan payant sur gitlab.com.

Stocker le token de déploiement en variable CI/CD

Dans le projet qui doit puller l’image, va dans Settings > CI/CD > Variables et ajoute :

  • DEPLOY_TOKEN_USER : le username du deploy token (ex: gitlab+deploy-token-123)
  • DEPLOY_TOKEN_PASS : la valeur du token (marque-le Masked pour ne pas l’afficher dans les logs)
🔴

Ne jamais hard-coder un token dans le .gitlab-ci.yml

Le fichier .gitlab-ci.yml est commité dans le repo. N’y mets jamais de valeur de token en clair, utilise toujours des variables CI/CD GitLab, qui sont chiffrées au repos et masquées dans les logs.

Rendre une image publique : quand et comment

Par défaut, la registry GitLab suit la visibilité du repo : privé si le repo est privé, public si le repo est public. Dans certains cas, rendre une image publique a du sens.

Bons cas d’usage pour une image publique

  • Un outil open source que tu veux partager librement
  • Une image de base générique (ex : PHP + Composer + Node) réutilisable par d’autres
  • Un projet communautaire ou un repo public GitLab servant de démo
  • Simplifier le pull sans authentification dans des environnements tiers
🔴

Ne jamais rendre publique une image qui contient

  • Des secrets ou variables d’environnement baked dans l’image
  • Du code propriétaire client ou métier
  • Des certificats ou clés privées copiés dans le filesystem

Rendre le repo GitLab public

La méthode la plus simple : passer le repo en public dans GitLab (Settings > General > Visibility). La registry devient automatiquement accessible en lecture sans authentification. N’importe qui peut alors faire :

docker pull registry.gitlab.com/votre-namespace/votre-repo:latest

Rendre uniquement la registry publique (repo privé)

GitLab permet aussi de garder le code source privé tout en exposant la registry publiquement. Dans Settings > Packages and registries > Container Registry, tu peux activer la visibilité publique de la registry indépendamment du repo.

Utile quand tu veux distribuer une image sans exposer le code source ni les pipelines CI/CD.

Utiliser Docker Hub pour les images vraiment publiques

Si l’image est destinée à une diffusion large (communauté open source, projet connu), Docker Hub reste la référence : meilleure indexation, pulls sans authentification sur toutes les plateformes, intégration native dans la doc officielle. Pour une image interne ou semi-publique, la registry GitLab suffit largement.

FAQ

Quelle est la limite de stockage pour la registry GitLab Free ?
Sur gitlab.com, le plan Free inclut 5 Go de stockage pour les artefacts, la registry et les packages combinés. Au-delà, il faut passer au plan Premium. Si tu héberges ta propre instance GitLab, la limite dépend de ton espace disque.
Comment supprimer les anciennes images pour libérer de l’espace ?
GitLab propose une politique de nettoyage automatique dans Settings > Packages and registries > Cleanup policies. Tu peux configurer la suppression des tags selon un pattern (ex: garder uniquement les 5 dernières versions, ou supprimer les tags plus vieux que 30 jours). Je recommande de l’activer sur tous les projets actifs.
Est-ce que la registry GitLab fonctionne avec Kubernetes ?
Oui, parfaitement. Tu crées un Secret de type kubernetes.io/dockerconfigjson avec les credentials de la registry, puis tu le références dans imagePullSecrets de ton Deployment. GitLab propose même une intégration Kubernetes native pour automatiser cette configuration.
Puis-je utiliser la registry GitLab avec Docker Compose sur un serveur de production ?
Oui. Tu fais un docker login registry.gitlab.com une fois sur le serveur avec un Deploy Token (scope read_registry), puis ton docker compose pull et docker compose up -d fonctionnent normalement. Je recommande de stocker le token dans un fichier .env ou de le lire depuis un vault plutôt que de le saisir interactivement.
Comment accélérer le build Docker dans le pipeline GitLab CI ?
La technique la plus efficace est le cache de layers via --cache-from et BUILDKIT_INLINE_CACHE=1 (voir section pipeline ci-dessus). Pour aller plus loin, tu peux aussi utiliser des GitLab Runners avec un cache local ou basculer sur Kaniko pour les builds en mode rootless. Sur un runner dédié (self-hosted), le cache persiste entre les jobs, ce qui peut diviser les temps de build par 3 à 5.
Comment scanner mes images Docker pour des vulnérabilités depuis GitLab ?
GitLab intègre un scanner de conteneurs (Container Scanning) basé sur Trivy ou Grype. Ajoute simplement le template include: template: Container-Scanning.gitlab-ci.yml à ton pipeline. Sur le plan Free, les résultats sont visibles dans les rapports de sécurité du pipeline. C’est une pratique que j’intègre systématiquement pour mes clients.

Conclusion

La registry Docker GitLab est, selon moi, la solution la plus pragmatique pour qui utilise déjà GitLab. Pas de service tiers supplémentaire, pas de coût additionnel sur les plans usuels, et une intégration CI/CD qui élimine la gestion manuelle des credentials dans les pipelines.

Le flux que je recommande en production : Dockerfile minimal + utilisateur non-root + .gitlab-ci.yml avec cache de layers + cleanup policy activée + Deploy Tokens par environnement. C’est robuste, auditable et reproductible.

Si tu veux aller plus loin sur l’automatisation de ton infra Docker et GitLab CI, jette un oeil à mon article sur la gestion des variables et secrets GitLab CI et à comment je construis des images Docker PHP production.

Tu veux externaliser la gestion de ton infra Docker et GitLab ?

Je m’occupe de la mise en place, de la sécurisation et de la maintenance de tes pipelines CI/CD et de ton infra conteneurisée. Devis gratuit, réponse sous 24h.

Contacte-moi ->

Laisser un commentaire