GitLab Runner: Construction d'images Docker

Construisez et poussez des images Docker depuis vos pipelines GitLab CI/CD en utilisant votre runner Stackhero et Docker-in-Docker

👋 Bienvenue sur la documentation de Stackhero !

Stackhero vous propose une solution GitLab Runner cloud simple à utiliser, conçue pour exécuter efficacement vos jobs GitLab CI/CD. Voici ce dont vous pouvez bénéficier :

  • Minutes CI/CD illimitées : aucune facturation à la minute, vos pipelines s'exécutent quand vous en avez besoin.
  • Jobs simultanés : lancez plusieurs jobs en parallèle pour accélérer l'ensemble de votre pipeline.
  • Docker executor avec prise en charge de Docker-in-Docker : facilitez la création et le push de vos images de conteneurs.
  • Compatible avec GitLab.com ainsi que toute instance GitLab auto-hébergée.
  • Une VM privée et dédiée propulsée par des disques NVMe/SSD rapides pour des builds fiables et constants.
  • Disponible dans les régions 🇪🇺 Europe et 🇺🇸 USA.

Gagnez du temps : connectez votre premier GitLab Runner et lancez vos pipelines en quelques minutes seulement !

Lorsque vous utilisez un GitLab Runner Stackhero, il exécute les jobs avec l'executor Docker. Cela signifie que chaque job démarre dans un nouveau conteneur basé sur l'image que vous indiquez. Si vous souhaitez construire vos propres images Docker dans votre pipeline, vous pouvez profiter de Docker-in-Docker (DinD). Cette configuration permet à un démon Docker de tourner à côté de votre job, ce qui vous permet d'exécuter des commandes comme docker build et docker push directement dans votre pipeline.

L'un des grands avantages ici est que votre runner dispose de minutes CI/CD illimitées. Vous pouvez construire des images aussi souvent que vous le souhaitez. De plus, comme votre cache de build est stocké sur le disque dédié du runner, les builds répétés peuvent réutiliser les couches précédentes, ce qui accélère considérablement vos pipelines.

Voici un exemple de .gitlab-ci.yml que vous pouvez ajouter à votre dépôt. Cette configuration construit le Dockerfile situé à la racine de votre projet :

build-image:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker info
  script:
    # Remplacez "my-image" par le nom souhaité :
    - docker build -t my-image .
    # Vous pouvez éventuellement lancer un test rapide sur l'image construite :
    # - docker run --rm my-image /path/to/tests

Dans cette configuration, le service docker:27-dind démarre le démon Docker. La variable DOCKER_TLS_CERTDIR: "/certs" active une connexion TLS sécurisée entre votre job et le démon Docker.

GitLab fournit plusieurs variables prédéfinies (CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_REGISTRY_IMAGE) afin que votre pipeline puisse se connecter et pousser des images vers le registre de conteneurs du projet sans avoir besoin d'autres secrets.

Voici un exemple de job qui construit et pousse votre image :

build-and-push:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
    # Si vous êtes sur la branche par défaut, vous pouvez aussi taguer et pousser "latest" :
    - |
      if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
        docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" "$CI_REGISTRY_IMAGE:latest"
        docker push "$CI_REGISTRY_IMAGE:latest"
      fi

Si vous souhaitez pousser vos images vers un autre registre (comme Docker Hub ou un registre privé), vous pouvez stocker ces identifiants comme variables CI/CD et les utiliser avec docker login de la même manière.

Comme le disque de votre runner est persistant entre les pipelines, vous pouvez accélérer les builds en réutilisant les couches d'images précédentes comme cache. Voici comment configurer cela :

build-cached:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    # Essayez de récupérer la dernière image pour alimenter le cache (ce n'est pas grave si elle n'existe pas encore) :
    - docker pull "$CI_REGISTRY_IMAGE:latest" || true
    - docker build --cache-from "$CI_REGISTRY_IMAGE:latest" -t "$CI_REGISTRY_IMAGE:latest" .
    - docker push "$CI_REGISTRY_IMAGE:latest"

Cette méthode permet à vos pipelines de s'exécuter plus rapidement au fil du temps en tirant parti du cache de couches Docker.

Votre offre détermine combien de jobs peuvent s'exécuter simultanément. Les jobs d'une même étape démarrent ensemble, dans la limite de votre niveau de parallélisme. Cela signifie qu'une étape contenant plusieurs jobs indépendants se termine dès que le job le plus lent est terminé, au lieu d'exécuter tous les jobs les uns après les autres.

Voici un exemple simple :

stages:
  - test

unit:
  stage: test
  image: node:22
  script: npm run test:unit

integration:
  stage: test
  image: node:22
  script: npm run test:integration

e2e:
  stage: test
  image: node:22
  script: npm run test:e2e

Si vous définissez votre parallélisme à 3 ou plus, les jobs unit, integration et e2e s'exécuteront tous en même temps.

Si vous souhaitez approfondir la construction d'images Docker en CI, n'hésitez pas à consulter la documentation officielle GitLab.