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

TermMeaning
ImageA read-only blueprint that holds the app and its tools
ContainerA running copy of an image
DockerfileA text recipe that builds an image
RegistryAn 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 package

The 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"]
LineJob
FROMStarts from a base image with Java 17 installed
WORKDIRSets the working folder inside the container
COPYCopies the jar into the image
EXPOSEDocuments the port the app uses
ENTRYPOINTDefines 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.0

The -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 images

Passing 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.0

One 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:
      - db

Start 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-image

The 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.