## Intro

Les conteneurs en production sont faciles à démarrer, mais plus difficiles à exploiter de manière cohérente. Un guide pratique montre quoi configurer, quelle commande prouve que la configuration fonctionne et à quoi ressemble un échec lorsque la configuration est incorrecte. Cet article explique comment réduire la taille des images Docker avec les builds multi-étapes, BuildKit, le cache de couches et les motifs de Dockerfile qui accélèrent les builds et simplifient la maintenance. L'objectif est de comprendre les éléments en jeu, de les tester localement et d'éviter les surprises lorsque le même motif est réutilisé dans un pipeline CI/CD (Continuous Integration/Continuous Deployment) : intégration continue / déploiement continu ou dans un environnement de type production.

## Workflow Overview

Commencez par identifier la ressource à optimiser (l'image finale), le changement de configuration qui l'affecte (la structure du Dockerfile et les fonctionnalités de BuildKit) et la commande qui prouve que la configuration fonctionne (construction avec BuildKit activé et mesure de la taille de l'image résultante). Gardez le flux pratique : configurez une chose, vérifiez l'état observé, puis documentez ce qui casse lorsque la configuration est absente, mal configurée ou utilisée dans un environnement de type production.

En pratique, l'aperçu du workflow est l'endroit où les équipes découvrent des hypothèses cachées. Les chemins locaux, les étiquettes d'image, les noms de réseau, les fichiers d'environnement, les limites de ressources et les permissions peuvent se comporter différemment sur les postes de travail, les runners et les hôtes de production. Rendez ces hypothèses explicites avant de vous fier à la configuration.

Concepts clés : optimisation d'image Docker, builds multi-étapes Docker, Docker BuildKit, mise en cache des couches Docker, bonnes pratiques Dockerfile. Des domaines connexes tels que les opérations Docker en production, les bonnes pratiques Dockerfile et la sécurité Docker sont importants car le comportement des conteneurs n'est rarement isolé : un choix de stockage peut affecter le déploiement, le débogage, la sauvegarde et les décisions de restauration.

Exemple concret : un service Go construit dans une étape builder à partir de l'image golang:1.22 , puis copié dans une étape minimale scratch . Activez BuildKit avec DOCKER_BUILDKIT=1 docker build -t myapp:latest . et vérifiez la taille avec docker images myapp:latest . Si l'image finale dépasse 10 Mo, la copie multi-étapes a probablement manqué un --chown ou a laissé des artefacts de construction dans la couche finale.

Vérifications Docker pratiques : exécutez docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" pour voir ce qui tourne, docker logs <conteneur> --tail 100 pour lire les derniers échecs, et docker inspect <conteneur> lorsque vous avez besoin des montages, réseaux, variables d'environnement ou de l'état de santé. Pour les projets Compose, utilisez docker compose ps , docker compose logs -f <service> et docker compose exec <service> sh pour déboguer sans modifier l'image.

Lorsque des données sont en jeu, confirmez où les fichiers sont stockés avant de modifier les conteneurs. Un volume nommé tel que app_data:/var/lib/app est géré par Docker et plus facile à réutiliser lors des reconstructions de conteneur. Un montage bind tel que ./data:/var/lib/app associe directement un répertoire hôte et est utile pour le développement local, mais il peut exposer des problèmes de permissions, de portabilité et de sauvegarde si le même chemin n'existe pas sur une autre machine.

Un petit test de type production local devrait inclure un test de redémarrage : arrêtez le conteneur, recréez-le et confirmez que l'application voit toujours les fichiers attendus. Si les données disparaissent, le service écrivait probablement dans le système de fichiers du conteneur au lieu d'un volume ou d'un montage.

## Local Pilot Plan

Le plan pilote local transforme le workflow en une expérience répétable et minimale. Créez un répertoire temporaire, ajoutez un minuscule programme Go ( main.go qui affiche « hello » et se termine) et écrivez un Dockerfile à deux étapes :

# syntax=docker/dockerfile:1.4
FROM golang:1.22 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app main.go

FROM scratch
COPY --from=builder /app /app
ENTRYPOINT [
\"\/app\"
] 
 Construisez avec BuildKit activé : DOCKER_BUILDKIT=1 docker build -t pilot:local . . Mesurez la taille de l'image : docker images pilot:local . Attendez un résultat inférieur à 5 Mo. Exécutez le conteneur : docker run --rm pilot:local et vérifiez la sortie. Puis arrêtez et supprimez le conteneur, relancez-le et confirmez que la même sortie apparaît — cela valide que le binaire est autonome et qu'aucune couche cachée ne subsiste.

Pendant le pilote, surveillez les pièges courants :

- Oublier CGO_ENABLED=0 produit un binaire lié dynamiquement qui échoue dans scratch .

- Omettre --from=builder copie toute l'image builder, gonflant la taille.

- Ne pas utiliser la syntaxe docker/dockerfile:1.4 désactive les fonctionnalités BuildKit telles que les montages de cache.

Documentez les commandes exactes utilisées pour construire, exécuter, inspecter, arrêter et recréer le conteneur. Comparez le résultat avec des domaines connexes tels que les opérations Docker en production, les bonnes pratiques Dockerfile et la sécurité Docker afin que l'implémentation s'inscrive dans le modèle d'exploitation global.

## Conclusion

L'optimisation d'image Docker avec les builds multi-étapes et BuildKit fonctionne le mieux lorsque l'équipe traite la configuration comme quelque chose à tester, et non seulement à copier. La voie la plus sûre consiste à garder les exemples petits, à exécuter les commandes localement et à confirmer le comportement attendu avant d'ajouter d'autres services ou de l'automatisation.

Pour une prochaine étape, choisissez un service et documentez les commandes exactes utilisées pour construire, exécuter, inspecter, arrêter et le recréer. Puis comparez le résultat avec des domaines connexes tels que les opérations Docker en production, les bonnes pratiques Dockerfile et la sécurité Docker afin que l'implémentation s'inscrive dans le modèle d'exploitation global.

Un flux de travail de conteneur fiable doit rendre l'échec visible : les journaux doivent être faciles à trouver, les données persistantes doivent survivre aux reconstructions de conteneur, et le comportement local doit être suffisamment proche de la production pour détecter les erreurs tôt.