As applications move toward microservices and containerized deployments, Docker has become the go-to tool for packaging Spring Boot applications. In this complete guide, youโll learn how to dockerize Spring Boot application using best practices.
๐ฆ What Youโll Learn
- What Docker is and why itโs useful for Spring Boot
- How to write a
Dockerfile
for your application - Creating
.dockerignore
- Building and running a Docker image
- Externalizing configuration for different environments
- Optimizing the image using JAR layering
- Multi-stage builds (optional teaser for next blog)

๐งฐ Prerequisites
Make sure you have the following installed:
- Java 17 or 21
- Maven or Gradle
- Docker CLI
- A sample Spring Boot application
๐ Step 1: Sample Spring Boot App
Letโs start with a simple Spring Boot app.
Package: com.kscodes.springboot.containers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.kscodes.springboot.containers; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/") public String hello() { return "Hello from Dockerized Spring Boot!"; } } |
๐๏ธ Step 2: Add Spring Boot Plugin (Maven)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- pom.xml --> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> <configuration> <layers>true</layers> <!-- Enables layered JAR --> </configuration> </plugin> </plugins> </build> |
๐ Step 3: Create Dockerfile
Create a file named Dockerfile
in the project root.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Stage 1 - Build stage (optional for multi-stage) FROM eclipse-temurin:21-jdk AS builder WORKDIR /app COPY . . RUN ./mvnw clean package -DskipTests # Stage 2 - Runtime image FROM eclipse-temurin:21-jre WORKDIR /app ARG JAR_FILE=target/*.jar COPY --from=builder ${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] |
๐ Step 4: Add .dockerignore
To speed up Docker builds and avoid bloated image layers, create a .dockerignore
:
1 2 3 4 5 6 7 8 |
target/ *.iml .idea/ .git/ *.md |
๐จ Step 5: Build Docker Image
1 2 3 4 |
docker build -t springboot-docker-app . |
โถ๏ธ Step 6: Run the Container
1 2 3 4 |
docker run -p 8080:8080 springboot-docker-app |
Navigate to http://localhost:8080 and you should see:
1 2 3 |
Hello from Dockerized Spring Boot! |
โ๏ธ Step 7: Externalize Configuration
Use environment variables or mount config files:
1 2 3 4 |
docker run -e SPRING_PROFILES_ACTIVE=prod -p 8080:8080 springboot-docker-app |
Or mount application.properties
:
1 2 3 4 5 |
docker run -v $(pwd)/config:/config \ -e SPRING_CONFIG_LOCATION=classpath:/application.properties,file:/config/ \ -p 8080:8080 springboot-docker-app |
๐ Step 8: Optimize with Layered JAR (Spring Boot 2.3+)
Spring Boot creates layered JARs to speed up Docker caching.
Run the below to inspect layers:
1 2 3 4 |
java -Djarmode=layertools -jar target/*.jar list |
Then update your Dockerfile (alternate approach):
1 2 3 4 5 6 7 8 9 |
FROM eclipse-temurin:21-jre WORKDIR /app COPY target/*.jar app.jar RUN java -Djarmode=layertools -jar app.jar extract EXPOSE 8080 ENTRYPOINT ["java", "-cp", "dependencies/:spring-boot-loader/:application/", "org.springframework.boot.loader.JarLauncher"] |
๐งช Step 9: Test with Docker Compose (Optional)
1 2 3 4 5 6 7 8 9 |
version: '3' services: springboot-app: image: springboot-docker-app ports: - "8080:8080" |
๐ก๏ธ Step 10: Best Practices
- Use
.dockerignore
to reduce context size - Avoid
latest
tag; use semantic versions - Use JDK only in build stage, JRE in runtime
- Minimize image layers
- Keep secrets out of images
๐ Summary
In this complete guide, you learned how to dockerize a Spring Boot application using a production-ready Dockerfile, .dockerignore
, and layered JAR optimization. You now understand how to build and run your app in a container, externalize configurations, and follow Docker best practices. This sets the foundation for more advanced topics like multi-stage builds, Kubernetes deployment, and cloud-native pipelines. Stay tuned for the next post in this DevOps for Spring Boot series!