Skip to content

feat: add Docker image caching to GitLab CI template #1

@damienlagae

Description

@damienlagae

Contexte

Le template GitLab CI généré par le coding standard installe les paquets apt et les extensions PHP dans le before_script de chaque job. Sur un pipeline complet (build, 4 lints, 2 analyze, test), ça représente ~8 fois la même séquence :

before_script:
  - apt-get update && apt-get install -y libicu-dev libzip-dev
  - docker-php-ext-install intl zip

C'est lent et redondant. On propose de builder une image Docker CI custom une seule fois et de la réutiliser dans tous les jobs.

Proposition

1. Nouveau template : templates/ci/gitlab/Dockerfile.tpl

Image basée sur php:<version>-cli avec tout pré-installé :

ARG PHP_VERSION=8.4
FROM php:${PHP_VERSION}-cli

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        git \
        unzip \
        libicu-dev \
        libzip-dev \
    && docker-php-ext-install intl zip pdo pdo_mysql \
    && pecl install pcov && docker-php-ext-enable pcov \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

À rendre dynamique selon $phpVersion, $databaseType (pdo_mysql vs pdo_pgsql, libpq-dev, etc.), comme le reste des templates.

2. Modifications dans templates/ci/gitlab-ci.yml.tpl

Ajouter une variable globale et mettre à jour l'anchor image :

variables:
  CI_IMAGE: $CI_REGISTRY_IMAGE/ci:php8.4

.php-image: &php-image
  image: $CI_IMAGE

Ajouter un job build:image en stage .pre qui utilise kaniko pour builder et pusher l'image dans le GitLab Container Registry :

build:image:
  stage: .pre
  image:
    name: gcr.io/kaniko-project/executor:v1.23.2-debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf '%s:%s' "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor
      --context "${CI_PROJECT_DIR}/.gitlab/ci"
      --dockerfile "${CI_PROJECT_DIR}/.gitlab/ci/Dockerfile"
      --destination "${CI_IMAGE}"
      --cache=true
      --cache-ttl=720h
  rules:
    - changes:
        paths:
          - .gitlab/ci/Dockerfile
    - if: $BUILD_CI_IMAGE == "true"
    - when: manual
      allow_failure: true

Note : l'authentification au Container Registry doit utiliser le format auth (base64 de user:password), pas le format username/password en clair — kaniko ne supporte pas ce dernier.

Supprimer tous les before_script avec apt-get / docker-php-ext-install / pecl install / curl composer des jobs build, lint, analyze. Seul le job phpunit garde un before_script pour le wait DB.

3. Génération du Dockerfile

Le init / update du coding standard doit aussi générer le Dockerfile dans .gitlab/ci/.

Résultat attendu

  • Premier run : build:image se déclenche (manuellement ou via changement du Dockerfile), build l'image en ~2m30, la push dans le registry
  • Runs suivants : les jobs pullent l'image depuis le registry, plus aucun apt-get ni docker-php-ext-install
  • Quand le Dockerfile change : kaniko rebuild uniquement les layers impactées grâce au cache (--cache=true)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions