Skip to content

Instantly share code, notes, and snippets.

@msauza
Last active November 26, 2023 15:49
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save msauza/6a906e879549e218c54868d81161afcb to your computer and use it in GitHub Desktop.
Save msauza/6a906e879549e218c54868d81161afcb to your computer and use it in GitHub Desktop.
Multi-Layer, Multi-Stage: Spring Boot application with Docker.

Overview

Spring Boot applications can run within a container by Multi-Layer based approach. Each layer may contain different parts of the application such as dependencies, source code, resources and even snapshot dependencies.

In the other hand, with Multi-Stage Build approach, any application can be built at a separate image from the final image that will contain the runnable application.

Spring Boot Docker

Multi-Layer

Build

$ ./gradlew clean build -x test

$ mkdir build/libs/dependency

$ (cd build/libs/dependency; jar -xf ../*.jar)

$ docker build -t myorg/myapp .

Run

$ docker run -p 8080:8080 myorg/myapp

.dockerignore

*
!build/libs/dependency/BOOT-INF/lib
!build/libs/dependency/BOOT-INF/classes
!build/libs/dependency/META-INF

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=build/libs/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.Application"]

Multi-Stage Build

Build

$ ./gradlew clean build -x test

$ mkdir build/libs/dependency

$ (cd build/libs/dependency; jar -xf ../*.jar)

$ docker build -t myorg/myapp .

Run

$ docker run -p 8080:8080 myorg/myapp

.dockerignore

*
!build/libs/dependency/BOOT-INF/lib
!build/libs/dependency/BOOT-INF/classes
!build/libs/dependency/META-INF

!gradlew
!gradle
!build.gradle
!settings.gradle
!src/main

Dockerfile

FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app

COPY gradle gradle
COPY build.gradle settings.gradle gradlew ./
COPY src src

RUN ./gradlew build -x test
RUN mkdir -p build/libs/dependency && (cd build/libs/dependency; jar -xf ../*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/build/libs/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.Application"]

Experimental

Dockerfile

# syntax=docker/dockerfile:experimental
FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app

COPY gradle gradle
COPY build.gradle settings.gradle gradlew ./
COPY src src

RUN --mount=type=cache,target=/root/.gradle ./gradlew build -x test
RUN mkdir -p build/libs/dependency && (cd build/libs/dependency; jar -xf ../*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/build/libs/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.Application"]

RUN

$ DOCKER_BUILDKIT=1 docker build -t myorg/myapp .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment