Spring Boot Docker
Docker packages an application together with everything it needs to run: Java, libraries, and settings. The package runs the same way on a laptop, a test server, and a cloud machine. Teams stop hearing the phrase "it works on my machine."
Spring Boot fits Docker well. An application builds into a single jar file, and a short Docker recipe wraps that jar in a portable container.
The Shipping Container Idea
Ports once handled cargo in random shapes, and loading took days. Standard shipping containers changed that. Any crane, ship, or truck could move a container because every container had the same outer shape, whatever it held inside. Docker containers work the same way. Servers handle a container identically, whatever application sits inside.
Developer laptop Test server Cloud
+--------------+ +--------------+ +--------------+
| Container | ==> | Container | ==> | Container |
| Java 17 | | Java 17 | | Java 17 |
| app.jar | | app.jar | | app.jar |
+--------------+ +--------------+ +--------------+
Same package, same behavior everywhere
Key Terms
| Term | Meaning |
|---|---|
| Image | A read-only blueprint that holds the app and its tools |
| Container | A running copy of an image |
| Dockerfile | A text recipe that builds an image |
| Registry | An online store for images, such as Docker Hub |
One image can start many containers, just as one cake recipe can bake many cakes.
Step 1: Build the Jar
mvn clean packageThe command creates a file such as target/shop-0.0.1-SNAPSHOT.jar. The jar already contains the embedded server, so no separate installation is needed.
Step 2: Write the Dockerfile
Place a file named Dockerfile in the project root.
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY target/shop-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]| Line | Job |
|---|---|
| FROM | Starts from a base image with Java 17 installed |
| WORKDIR | Sets the working folder inside the container |
| COPY | Copies the jar into the image |
| EXPOSE | Documents the port the app uses |
| ENTRYPOINT | Defines the start command |
Step 3: Build and Run
docker build -t shop-app:1.0 .
docker run -d -p 8080:8080 --name shop shop-app:1.0The -p flag connects port 8080 on the computer to port 8080 in the container. Visit http://localhost:8080 and the application responds.
Browser --> localhost:8080 --> [ Docker port map ] --> Container:8080 --> Spring Boot
Useful Commands
docker ps # list running containers
docker logs -f shop # follow application logs
docker stop shop # stop the container
docker rm shop # remove the container
docker images # list local imagesPassing Settings with Environment Variables
Spring Boot reads environment variables and maps them to properties. Names use uppercase letters and underscores.
docker run -d -p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/shop \
-e SPRING_DATASOURCE_USERNAME=shopuser \
-e SPRING_DATASOURCE_PASSWORD=change_me \
shop-app:1.0One image serves every environment, and the variables change only the settings. Keep real passwords out of the Dockerfile and out of source control.
Multi-Stage Builds
A multi-stage Dockerfile compiles the code inside Docker, so the build machine needs no Maven or Java.
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /src
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=build /src/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]The final image keeps only the small Java runtime and the jar. Build tools stay behind in the first stage, which shrinks the image.
Running App and Database Together
Docker Compose starts several containers from one file.
services:
db:
image: mysql:8
environment:
MYSQL_DATABASE: shop
MYSQL_ROOT_PASSWORD: change_me
app:
build: .
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/shop
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: change_me
depends_on:
- dbStart everything with docker compose up. The app reaches the database through the service name db.
Building Without a Dockerfile
Spring Boot can create an image through Cloud Native Buildpacks.
mvn spring-boot:build-imageThe command produces an optimized image with sensible defaults and needs only a running Docker engine.
Best Practices
- Choose a slim JRE base image to reduce size and attack surface.
- Add a .dockerignore file that skips target folders and local files.
- Tag images with version numbers instead of relying on the latest tag.
- Run the application as a non-root user in production images.
- Expose the Actuator health endpoint and use it for container health checks.
Docker turns a Spring Boot application into a portable, repeatable package. Teams ship faster and run the same build across every environment.
