Un build multi-étapes sert à ne pas livrer l’atelier avec le produit. Une première image compile, télécharge, teste si vous le voulez. Une seconde, plus petite, ne reçoit que l’artéfact — le jar, le binaire Go, le dossier dist/ — via COPY --from=builder.
Ce n’est pas un raffinement de taille. C’est une frontière de responsabilité : ce qui sert à construire n’a rien à faire dans ce qui s’exécute. Le compilateur, Maven, le cache ~/.m2, gcc, sont des outils. En production ils allongent le pull, et ils offrent à un attaquant ce qu’il faut pour compiler la suite.
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /app/target/app.jar ./app.jar
USER 10001
ENTRYPOINT ["java", "-jar", "app.jar"]Les étapes intermédiaires sont jetées. Seule la dernière FROM est l’image taguée.
Que vous ne réduisez pas ça à « pour que ce soit plus petit ». La taille est la conséquence. L’intention est la surface d’attaque et le contrat de runtime.
Il veut aussi voir que vous savez cacher les dépendances dans l’étape builder : copier le manifeste (pom.xml, go.mod, package-lock.json) avant les sources. Sinon le multi-étapes allège l’image finale et laisse le build aussi lent qu’avant.
Ce qu’un multi-étapes ne règle pas : un secret copié dans l’étape finale, un utilisateur root, un COPY . . sans dockerignore. Ce sont d’autres questions, et les coller ici est un signal faible.
Le déroulé Java, avec les ordres de grandeur, est dans alléger une image Docker Java.
« Je peux lancer les tests dans l’étape builder ? »
Vous pouvez. En entretien, la meilleure réponse est souvent : les tests appartiennent à la CI, avant le docker build. L’image devient l’artéfact d’un build déjà vert, pas l’endroit où l’on découvre qu’il est rouge — et où chaque développeur les rejoue pour démarrer l’app.
« Pourquoi pas une seule image Alpine avec tout dessus ? »
Parce que « tout dessus » est précisément ce qu’on veut quitter. Alpine aide le runtime ; elle n’excuse pas d’y laisser Maven.