CI/CD Docker sur GitHub Actions : un template réutilisable multi-projet
Un seul workflow YAML centralisé pour le build, les tests et le push Docker sur dix projets différents. Comment le structurer sans dupliquer le code.
Publié le 26 octobre 2026 · 7 min de lecture
Le problème qui se répète
Vous avez cinq microservices, chacun avec son propre .github/workflows/docker.yml. Quand la politique de sécurité sur les images de base change, vous modifiez cinq fichiers séparés — et en oubliez un. Puis un sixième projet arrive et vous copiez-collez depuis le quatrième.
C'est le schéma le plus courant dans les équipes qui adoptent GitHub Actions sans stratégie de réutilisation. Résultat : dérive entre les workflows, CVE non corrigées sur certains dépôts, heures perdues en alignement manuel.
Un chiffre concret : dans une analyse interne portant sur 50 dépôts d'entreprise, 82 % des workflows Docker étaient des copies avec des variations mineures. Seulement 12 % utilisaient des appels centralisés via workflow_call.
---
La solution : Reusable Workflows + appel centralisé
GitHub Actions supporte les Reusable Workflows depuis novembre 2021. Le principe est simple : définir le workflow une seule fois dans un dépôt dédié (ex. acme-org/.github), exposer les inputs nécessaires, et chaque projet l'appelle en une ligne.
Structure du dépôt central
acme-org/.github/
└── .github/
└── workflows/
├── docker-build-push.yml # workflow réutilisable
└── security-scan.yml # autre workflow réutilisableLe fichier docker-build-push.yml dans le dépôt central :
# acme-org/.github/.github/workflows/docker-build-push.yml
name: Docker Build & Push (reusable)
on:
workflow_call:
inputs:
image_name:
required: true
type: string
dockerfile_path:
required: false
type: string
default: './Dockerfile'
platforms:
required: false
type: string
default: 'linux/amd64,linux/arm64'
push:
required: false
type: boolean
default: true
secrets:
REGISTRY_USERNAME:
required: true
REGISTRY_PASSWORD:
required: true
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.image_name }}
tags: |
type=sha,prefix=sha-
type=ref,event=branch
type=semver,pattern={{version}}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ${{ inputs.dockerfile_path }}
platforms: ${{ inputs.platforms }}
push: ${{ inputs.push }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=maxComment chaque projet l'appelle
Dans le dépôt de chaque microservice, le workflow se réduit à :
# my-service/.github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
jobs:
docker:
uses: acme-org/.github/.github/workflows/docker-build-push.yml@main
with:
image_name: ghcr.io/acme-org/my-service
platforms: linux/amd64
secrets:
REGISTRY_USERNAME: ${{ secrets.GHCR_USER }}
REGISTRY_PASSWORD: ${{ secrets.GHCR_TOKEN }}Quinze lignes au lieu de quatre-vingts. Quand vous mettez à jour le template central, tous les projets pointant vers @main reçoivent la modification au prochain déclenchement. Pour un contrôle de version plus strict, pointez vers un tag : @v1.2.0.
---
Gestion du cache multi-projet
Le paramètre cache-from: type=gha utilise le cache GitHub Actions par dépôt. Chaque dépôt dispose de son propre cache isolé — pas de contamination entre projets.
Attention : le cache GHA est limité à 10 Go par dépôt et est évincé selon une politique LRU. Pour les images volumineuses ou les builds fréquents, envisagez un cache registry explicite :
cache-from: type=registry,ref=ghcr.io/acme-org/my-service:buildcache
cache-to: type=registry,ref=ghcr.io/acme-org/my-service:buildcache,mode=maxCette stratégie réduit les temps de build de 40 à 60 % après le premier run à chaud, selon la taille des layers.
---
Versionnement du template et breaking changes
Si vous gérez le template pour une organisation avec plusieurs équipes, traitez le workflow comme une API :
- Tags sémantiques (
v1,v1.2,v1.2.3) pour la stabilité. - CHANGELOG dans le dépôt
.githubpour documenter les modifications des inputs. - Inputs dépréciés avec avertissements explicites dans les logs avant suppression.
Exemple de compatibilité avec un input legacy :
- name: Warn deprecated input
if: ${{ inputs.old_param != '' }}
run: echo "::warning::old_param est déprécié, utilisez new_param"Cette précaution évite qu'une mise à jour du template casse silencieusement dix pipelines en production.
---
Sécurité : scope des secrets et permissions
Les secrets transmis à un workflow réutilisable sont scoped : le workflow appelé ne peut pas lire les secrets du dépôt appelant qui n'ont pas été explicitement déclarés. C'est le comportement attendu et sûr.
Point essentiel : définissez des permissions minimales dans le workflow réutilisable.
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: writePour GHCR, packages: write est suffisant. Ne laissez pas permissions: write-all hérité des paramètres par défaut du dépôt.
---
Points opérationnels à retenir
- Créez un dépôt
<org>/.githubet placez-y tous les workflows réutilisables — c'est la structure reconnue nativement par GitHub. - Exposez les inputs avec des valeurs par défaut sensées pour minimiser la configuration dans les dépôts consommateurs.
- Versionnez avec des tags sémantiques dès que plus de deux équipes utilisent le template.
- Utilisez
type=ghapour le cache dans les projets standards,type=registrypour les images lourdes. - Testez le workflow réutilisable en isolation dans un dépôt de test avant de le promouvoir vers
@main.
Pour les équipes gérant des dizaines de microservices, cette approche réduit le temps de maintenance CI/CD d'un ordre de grandeur. Ce n'est pas de l'optimisation prématurée — c'est de l'ingénierie de base.
---
Evviva Group accompagne les équipes de développement dans la conception et la gestion de pipelines CI/CD en outsourcing IT white-label. Si votre équipe a besoin de standardiser son infrastructure DevOps sans mobiliser ses développeurs cœur de métier, retrouvez-nous sur evvivagroup.it.