E-NO
DevOps 7 min de lecture

Pipelines GitLab CI/CD pour construire et publier des images Docker : guide pratique avec BuildKit et mise en cache

calendar_today Publié : 2026-07-08
update Dernière mise à jour : 2026-07-08
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Pipelines GitLab CI/CD pour construire et publier des images Docker : guide pratique avec BuildKit et mise en cache ».

Introduction

Expédier des images Docker via GitLab CI/CD vous offre un chemin répétable et auditable du code vers un conteneur en cours d'exécution. Dans ce guide, vous configurerez un pipeline pratique qui construit et publie des images, comprendrez les compromis du Docker-in-Docker, activerez BuildKit pour la vitesse, appliquerez un étiquetage et une mise en cache fiables, et testerez le tout en toute sécurité sur un GitLab Runner local avant de l'utiliser en production.

Aperçu du flux de travail

Un flux de travail de production typique se présente ainsi :

  • Le développeur pousse du code vers GitLab (par exemple, une branche de fonctionnalité feature/login).
  • GitLab CI construit une image Docker avec BuildKit.
  • Le job se connecte au registre de conteneurs GitLab.
  • Le job étiquette l'image avec le SHA du commit (abc1234), le slug de la branche (feature-login), et optionnellement latest pour la branche par défaut.
  • Le job pousse toutes les étiquettes vers le registre.
  • Optionnel : un job de déploiement tire l'image par étiquette et lance le conteneur.

Préparer les fichiers du projet

  1. Créez un Dockerfile optimisé pour la mise en cache :
# syntax=docker/dockerfile:1.7
FROM node:20-alpine AS base
WORKDIR /app
# Installer les dépendances de prod avec le cache npm
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
# Copier le reste en dernier pour maximiser la réutilisation des couches
COPY . .
EXPOSE 3000
CMD ["node", "server.js" ]
  1. Ajoutez un .dockerignore pour garder le contexte de construction petit :
node_modules
.git
.gitlab
Dockerfile*
*.log
  1. Optionnellement, ajoutez un docker-compose.yml pour des tests locaux :
services:
  web:
    build: .
    ports:
      - "3000:3000"

Choix de la stratégie de construction

Vous avez deux façons courantes d'exécuter des constructions Docker dans GitLab CI :

A) Docker-in-Docker (DinD)

  • Fonctionnement : l'image du job est docker:24 et un service docker:24-dind exécute le démon Docker à l'intérieur de l'environnement du job.
  • Avantages : portable, autonome, cohérent entre les runners.
  • Inconvénients : nécessite un runner privilégié, peut être plus lent au démarrage, sauts réseau supplémentaires.

B) Socket Docker hôte (exécuteur shell ou Docker avec /var/run/docker.sock)

  • Fonctionnement : le job communique avec le démon Docker de l'hôte.
  • Avantages : constructions généralement plus rapides, pas de configuration DinD.
  • Inconvénients : accès plus large au Docker de l'hôte, durcissement du runner plus strict requis.

Choisissez celle qui correspond à votre politique de runner et à votre posture de sécurité. Pour la plupart des équipes qui débutent, DinD est un défaut simple. À mesure que vous grandissez, le Docker hôte peut améliorer les performances si vous acceptez les compromis de sécurité.

Activer BuildKit

BuildKit accélère les constructions, améliore la mise en cache et active des fonctionnalités comme les montages de cache et les secrets. Activez-le en définissant DOCKER_BUILDKIT=1 et en utilisant docker buildx pour les options de cache avancées.

Points clés :

  • Utilisez la directive de syntaxe dans votre Dockerfile pour les fonctionnalités modernes.
  • Gardez le COPY des manifestes de paquets avant les fichiers sources pour réutiliser les couches de dépendances.
  • Utilisez --mount=type=cache dans les étapes RUN qui téléchargent des paquets (comme montré dans le Dockerfile ci-dessus pour npm).

Configuration du pipeline GitLab CI

Cet exemple utilise DinD, se connecte au registre de conteneurs GitLab, applique des étiquettes sûres et pousse les images. Enregistrez sous .gitlab-ci.yml.

stages: [build, push]

image: docker:24

services:
  - name: docker:24-dind

variables:
  DOCKER_TLS_CERTDIR: ""
  DOCKER_DRIVER: overlay2
  DOCKER_BUILDKIT: "1"
  IMAGE: $CI_REGISTRY_IMAGE
  TAG_SHA: $CI_COMMIT_SHORT_SHA
  TAG_BRANCH: $CI_COMMIT_REF_SLUG
  TAG_LATEST: latest

before_script:
  - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"

build:
  stage: build
  script:
    - docker info
    - docker buildx create --name ci-builder --use || true
    - docker buildx inspect --bootstrap
    - >
      docker buildx build
      --pull
      --push
      --progress=plain
      --tag "$IMAGE:$TAG_SHA"
      --tag "$IMAGE:$TAG_BRANCH"
      --cache-from=type=registry,ref="$IMAGE:buildcache"
      --cache-to=type=registry,ref="$IMAGE:buildcache",mode=max
      --file Dockerfile .

push:
  stage: push
  script:
    - docker pull "$IMAGE:$TAG_SHA"
    - docker tag "$IMAGE:$TAG_SHA" "$IMAGE:$TAG_LATEST"
    - docker push "$IMAGE:$TAG_LATEST"
  rules:
    - if: $CI_COMMIT_REF_NAME == "main" || $CI_COMMIT_REF_NAME == "master"

Notes :

  • $CI_REGISTRY, $CI_REGISTRY_IMAGE, $CI_REGISTRY_USER et $CI_REGISTRY_PASSWORD sont fournis par GitLab quand le registre de conteneurs est activé sur le projet.
  • La première construction n'aura pas d'image de cache ; BuildKit avertira mais continuera.
  • Si vous utilisez le Docker hôte au lieu de DinD, supprimez services, assurez-vous que votre runner a Docker disponible, et gardez les mêmes étapes de script.

Stratégie de cache

La mise en cache des couches est votre principal levier pour des constructions plus rapides.

Étapes pratiques :

  • Ordonnez les instructions du Dockerfile pour maximiser la réutilisation : installation des dépendances d'abord, puis code de l'application.
  • Utilisez les montages de cache BuildKit pour les gestionnaires de paquets (ex. : RUN --mount=type=cache,target=/root/.npm npm ci).
  • Publiez et tirez un cache de registre avec buildx --cache-to et --cache-from (comme montré dans le pipeline).
  • Gardez le contexte de construction léger avec .dockerignore pour éviter d'invalider le cache.

Plan pilote local

Commencez avec un pilote petit et facile à mesurer pour tout vérifier localement avant le déploiement.

Périmètre du pilote :

  • Un petit service avec un Dockerfile simple.
  • Métriques de succès : temps de construction, taille de l'image, temps de démarrage du conteneur, capacité à pousser et tirer.

Étapes :

  1. Construisez localement avec BuildKit :
DOCKER_BUILDKIT=1 docker build -t app:dev .
  1. Exécutez localement avec Docker Compose :
docker compose up --build

Visitez http://localhost:3000 pour confirmer que ça fonctionne.

  1. Installez un GitLab Runner local et lancez le job de construction :
gitlab-runner exec docker build   # exécuteur docker
# ou
gitlab-runner exec shell build    # exécuteur shell avec Docker hôte
  1. Poussez une branche de test vers GitLab et confirmez que l'image apparaît dans le registre du projet avec les étiquettes attendues ($CI_COMMIT_SHORT_SHA et $CI_COMMIT_REF_SLUG).

Gardez le pilote étroit, mesurable et facile à inspecter. Étendez à plus de services seulement après avoir atteint les métriques.

Dépannage et pièges

Problèmes courants et correctifs rapides :

  • Échec de connexion : Assurez-vous que le registre du projet est activé et que $CI_REGISTRY_USER et $CI_REGISTRY_PASSWORD sont présents. Pour les branches protégées, confirmez que le runner a la permission de pousser.
  • DinD nécessite un runner privilégié : Si les constructions échouent avec des erreurs de démon, configurez le runner avec privileged = true dans config.toml ou utilisez un runner qui autorise les conteneurs privilégiés.
  • Pas de cache sur la première construction : Sans danger à ignorer. La deuxième construction devrait être plus rapide si les étiquettes sont les mêmes et le contexte stable.
  • Constructions lentes : Ajoutez ou améliorez .dockerignore, gardez l'ordre COPY optimisé, et utilisez les montages de cache BuildKit. Envisagez le Docker hôte si autorisé.
  • Collisions d'étiquettes : Utilisez le SHA de commit pour des étiquettes immuables. Utilisez latest seulement sur main ou master.
  • Images volumineuses : Passez à des bases alpine ou distroless quand possible, et gardez les artefacts de construction hors de l'image finale.
  • Secrets dans les images : Ne cuisez pas de secrets dans les couches. Utilisez des arguments de construction ou des variables d'environnement à l'exécution et vérifiez avec docker history.

Conclusion

Vous avez maintenant un pipeline GitLab CI pratique qui construit et publie des images Docker avec des étiquettes sensées, l'accélération BuildKit et une stratégie de cache. Commencez avec le pilote local, vérifiez les métriques, puis étendez à plus de services. Réévaluez votre choix de stratégie de construction (DinD vs Docker hôte) à mesure que vous grandissez, et gardez le Dockerfile léger pour préserver des constructions rapides et fiables.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO