Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Optimisation du Dockerfile et Dockerfile.debug

Date de l'article:01-01-2026
Docker CI/CD Github-Actions
On remplace l'image de base et observons la possibilité d'un Dockerfile.debug en parallèle. Nous ferons la comparaison des approches et verrons comment, le positionnement d'Actuator peut devenir une alternative au debug via container
Avant de décider quoi que ce soit, il faut se renseigner, savoir pourquoi et dans quel cas on changerait l'image;
Les objectifs seront de réduire la surface d'attaque, forcer l'exécution en "utilisateur non-root", et ne conserver que le runtime Java nécessaire
Comparatifs technique
Options temurin:17-jre-alpine distroless/java17
Shell disponible Oui (sh) Non
Package manager Oui (apk) Non
Utilisateur root Oui par défaut Nonroot fourni
Surface d'attaque Moyenne Minimale
Debug facile Oui Non
Usage recommandé Dev / Debug Production
Points importants pour l'image "distroless"
L'image ne contient aucun outil inutile (shell, gestionnaire de paquets)
→ On ne peut pas “entrer” dans le conteneur avec une commande "sh"
L'utilisation d'un USER nonroot utilise le principe du moindre privilège, conforme aux standards sécurité cloud
→ Distroless fournit cet utilisateur
L'image java17-debian12, basée sur Debian 12 (glibc)
Garantit la compatibilité avec: PostgreSQL, Oracle, drivers JDBC natifs et
les librairies natives éventuelles

Modification de l'image Docker
Dans le premier pipeline, nous utilisions l'image JRE Alpine. Et, bien que cette image soit déjà bien optimisée, légère et avec de bonne performance;
Pour un environnement de production, on peut aller plus loin, en matière de sécurité et de réduction de surface d'attaque
Ancienne image utilisée: JRE Alpine
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY target/flashcards-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
update 05/05/26: L'image debian12 représentant trop de Vulnérabilités, je l'ai modifiée en debian13:nonroot
Modifiée, comme ceci:
FROM gcr.io/distroless/java17-debian12
WORKDIR /app
COPY target/flashcards-*.jar app.jar

USER nonroot
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Dockerfile et Dokerfile.debug
Au vue du comparatif, sachant qu'elle impose des restrictions, vient alors tout naturellement l'idée d'utiliser un Dockerfile.debug
Pourquoi utiliser une image debug?
Une image distroless ne permets pas:
D'avoir un shell, impossible de faire: docker exec -it container sh
L'installation d'outils
L'inspection simple des fichiers
Des commandes ping - curl - wget
D'analyse rapide du réseau
En quoi consiste le Dockerfile.debug ?
L'idée est simple: Avoir deux images différentes, pour deux usages différents
Image Objectif
Dockerfile Production sécurisée
Dockerfile.debug Développement / Investigation

Cela change la culture d'investigation.
Lors d'incident en production, cela peut compliquer l'analyse


Exemple de Dockerfile "debug" en parallèle
# Dockerfile.debug
FROM eclipse-temurin:17-jre-slim

WORKDIR /app
COPY target/flashcards-*.jar app.jar

RUN useradd -m appuser && chown -R appuser /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
On peut alors construire et taguer différemment:
# prod (distroless):
docker build -f Dockerfile -t val7304/flashcards:prod .
# debug:
docker build -f Dockerfile.debug -t appuser/flashcards:debug .

Cela permet d'avoir: en Prod: Une image légère et sécurisée (distroless)
en local (debug/incident): L'image avec shell et outils installables (temurin-slim)

Quand créer/garder un Dockerfile.debug ?
→ Si l'équipe est large, l'infra complexe, ou que l'on utilise Kubernetes.
→ Si on a fréquemment besoin de troubleshooting "bas niveau" ou, si l'on ne dispose pas encore de système d'observabilité mature

D'un point de vue DevOps
Dans un environnement bien conçu, on n'entre pas dans le container
      On utilise:
→ Les logs centralisés
→ Les metrics Prometheus et les Dashboards Grafana, l'alerting
→ Actuator
APM (si présent)

L'accès au shell devient un anti-pattern.
     Et c'est précisément l'argument fort pour utiliser une image distroless

L'utilisation de distroless n'est pas un simple choix esthétique, c'est aussi une décision de sécurité et une discipline d'immutabilité

Cas réels où on entre dans un container
Idéalement on ne le fait pas, mais dans la réalité: Il existe des cas où cela arrive
Incident critique inexpliqué:
L'application ne répond plus, le CPU est à 100%, les sont threads bloqués
On peut vouloir: Inspecter/Vérifier des fichiers ou la config, analyser un dump
Problème réseau complexe
DNS mal résolu, connexion DB instable, problème de proxy
On peut vouloir: tester les commandes ping, curl, nslookup, netstat
! Mais Pas dans une image prod hardened
Fuite mémoire avancée:
On peut vouloir: Générer un heap dump, l'extraire et l'analyser

Actuator, l'alternative au Docker debug
À ce stade, comme nous avons déja configuré Actuator et la classe Sécurité,
nous pouvons simplement ajouter les nouveaux indicateurs à la suite, dans le(s) fichier(s) de configuration du profil
Ajout de 2 indicateurs dans l'application Flashcards

En dev, nous avions déjà activé:
health, info, metrics, mappings, env, configprops, loggers

En [staging] Ajoutez: ", heapdump" en fin de liste

En [staging] / [prod]: Ajoutez
management.endpoint.env.show-values=never
pour éviter la fuite de secrets

En [prod], ajoutez: ", threaddump" en fin de liste


threaddump
Cas d'usage : Application bloquée, threads WAITING/BLOCKED, deadlock, pool saturé, problème Tomcat
Impact sécurité : faible

heapdump
Plus sensible, il permet un bump mémoire complet (capture instantanée de toute la mémoire allouée à la JVM), une analyse fuite mémoire, un diagnostic
Mais: Le fichier est lourd et peut contenir données sensibles qui pourrait avoir un impact momentané sur les performances

Recommandations & Améliorations possibles
Ajouter un health check dans le Dockerfile.debug

Est une bonne pratique complémentaire sur une image non-distroless et, peut être une alternative à un Healthcheck géré par un orchestrateur (Docker Compose /Kubernetes)
ou, à un monitoring externe

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s CMD \
  wget -qO- http://localhost:8080/actuator/health || exit 1
Le fichier ".dockerignore" doit toujours exclure, a minima:
.git
.gitignore
target/
node_modules/
README.md
Les builds seront plus rapides Le contexte Docker réduit
Une meilleure performance CI dans GitHub Actions

Conclusion pour le projet Flashcards
Pour un projet simple:
Le Dockerfile distroless est un choix production solide et moderne
Le Dockerfile.debug est utile mais pas obligatoire
Pour un petit service, Actuator remplace largement l'accès shell
Pour mon cas (petit service Spring Boot, Docker Hub, GitHub Actions)
Garder distroless pour la prod
→   Eventuellement, ajouter un Dockerfile.debug pour avoir
      accès au shell dans le container

Point important
     La mise à jour de certaines actions CI/CD (dependabot) sont succeptible d'engendrer des modifications dans les workflows, images et/ou le code,
     Le repository constitue, La source de vérité
Dans l'article suivant, je conclus brièvement et j'introduit plusieurs tableaux de suivis et de mises à jours pour le projet "Flashcards avec sa CI/CD Github Actions"

Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.