Spring Boot incontra Docker 2: multistage per immagini light
Le ultime versioni di Docker hanno introdotto un'interessante feature che consente di creare delle immagini "leggere": si tratta del multistage build.
In parole povere si tratta della possibilità di suddividere il processo di creazione delle immagini in fasi o stage in cui ciascuna di esse può riutilizzare gli artifacts prodotti in una delle precedenti.
Inoltre è possibile utilizzare un'immagine di base differente ad ogni stage.
Cerchiamo di chiarire il concetto con un esempio pratico.
Nel precedente post abbiamo visto come "dockerizzare" un'applicazione Spring Boot compilando direttamente il codice sorgente in Java. L'immagine prodotta pesa circa 136 MB perchè include il JDK che non è più necessario dopo la fase di build.
Grazie al multi-stage possiamo utilizzare l'immagine contenente Maven e l'ambiente di sviluppo per creare il jar dell'applicazione come nel codice di seguito riportato
FROM maven:3.5-jdk-8-alpine AS build
COPY src /usr/src/hello-docker/src
COPY pom.xml /usr/src/hello-docker
RUN mvn -f /usr/src/hello-docker/pom.xml clean package`
Da notare l'aggiunta AS build
che ci consente di riferirci allo stage di compilazione proprio con l'etichetta build. Infatti il passo successivo è di utilizzare una nuova immagine più leggera (openjdk 8 alpine), contenente il solo JRE, all'interno della quale importiamo l'applicazione compilata nella fase precedente.
Il comando COPY --from=<label stage>
permette di copiare dei file da uno stage all'altro.
FROM openjdk:8-jre-alpine
COPY --from=build /usr/src/hello-docker/target/hello-docker-0.0.1-SNAPSHOT.jar /usr/hello-docker/hello-docker-0.0.1-SNAPSHOT.jar`
Dopo aver generato l'immagine possiamo notare che le sue dimensioni si sono ridotte a circa 96 MB.