Working with Docker Deployment
1. Creating Dockerfile for Spring Boot
Example: Minimal Dockerfile with JRE
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY target/app.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
2. Using Multi-Stage Builds
Example: Multi-stage Maven build
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /src
COPY pom.xml .
RUN mvn -B -e -ntp dependency:go-offline
COPY src ./src
RUN mvn -B -e -ntp -DskipTests package
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /src/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
3. Building Docker Images (docker build)
Example: Build and tag Docker image
docker build -t myorg/orders:1.0 .
docker build --build-arg JAR=target/orders-1.0.jar -t myorg/orders:1.0 .
4. Running Containers (docker run)
Example: Run container with environment variables
docker run -d --name orders \
-p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/orders \
myorg/orders:1.0
5. Using Docker Compose (docker-compose.yml)
Example: Docker Compose with database health check
services:
app:
image: myorg/orders:1.0
ports: ["8080:8080"]
environment:
SPRING_PROFILES_ACTIVE: prod
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/orders
depends_on:
db: { condition: service_healthy }
db:
image: postgres:16-alpine
environment: { POSTGRES_PASSWORD: secret, POSTGRES_DB: orders }
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 10
6. Configuring Environment Variables
| Property | Env Var |
|---|---|
spring.profiles.active |
SPRING_PROFILES_ACTIVE |
spring.datasource.url |
SPRING_DATASOURCE_URL |
server.port |
SERVER_PORT |
Custom app.feature.x.enabled |
APP_FEATURE_X_ENABLED |
7. Managing Container Volumes
Example: Bind mount config and log volume
services:
app:
image: myorg/orders:1.0
volumes:
- app-logs:/var/log/app
- ./config:/config:ro
environment:
SPRING_CONFIG_ADDITIONAL_LOCATION: /config/
volumes:
app-logs:
8. Using Layered JAR Structure (spring-boot-jarmode-layertools)
Example: Layered JAR Dockerfile
FROM eclipse-temurin:21-jre-alpine AS extract
WORKDIR /app
COPY target/app.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=extract /app/dependencies/ ./
COPY --from=extract /app/spring-boot-loader/ ./
COPY --from=extract /app/snapshot-dependencies/ ./
COPY --from=extract /app/application/ ./
ENTRYPOINT ["java","org.springframework.boot.loader.launch.JarLauncher"]
9. Optimizing Image Size
| Technique | Effect |
|---|---|
| JRE base (not JDK) | ~150MB savings |
| Alpine / distroless | Minimal OS |
| Layered JAR | Better layer caching |
jlink custom JRE |
Tailored runtime |
| GraalVM native image | ~80MB self-contained |
10. Publishing Images to Registry
Example: Push image to container registry
docker login ghcr.io
docker tag myorg/orders:1.0 ghcr.io/myorg/orders:1.0
docker push ghcr.io/myorg/orders:1.0
# Or via Spring Boot buildpack
./mvnw spring-boot:build-image \
-Dspring-boot.build-image.imageName=ghcr.io/myorg/orders:1.0 \
-Dspring-boot.build-image.publish=true