Логотип Workflow

Article

Updated at:

Docker For Spring Boot Developers

Stage 8 - Docker for Spring Boot Developers

For a Spring Boot developer, Docker is useful when it makes the application, database, and tests repeatable. The main artifact is usually an executable JAR built by Maven or Gradle.

Docker Docker for Spring Boot Developers

From JAR to container

The simplest containerization path is: build the JAR, copy it into a Java runtime image, and run java -jar. This is easy to understand and good for the first production-like image.

mvn package
copy JAR into runtime image
run app with Compose database
run Testcontainers integration tests

Why layered JARs matter

Optimization starts when builds become slow. Spring Boot layered JARs separate dependencies, loader, snapshot dependencies, and application classes. Docker can then reuse dependency layers when only controller or service code changes.

Real database tests

Testcontainers brings the same idea into integration tests. Instead of mocking PostgreSQL behavior, the test starts a real PostgreSQL container. Repository tests then run against a real database engine with real SQL behavior.

What belongs in the image

A Spring Boot runtime image should contain the Java runtime and the application artifact. It should not contain the whole local Gradle cache, IDE files, test reports, or developer credentials. Multi-stage builds help separate build tools from runtime files.

The simplest image can copy a JAR directly. A more advanced image can extract layers from the Spring Boot JAR so dependencies and application code are cached separately. The right choice depends on project size and CI speed requirements.

For a beginner, start simple. Build a correct image first, then optimize after you can explain what changed.

Compose as local infrastructure

Most Spring Boot services are not useful alone. They need a database, sometimes Redis, sometimes Kafka, and sometimes a migration tool. Compose lets the team describe that local infrastructure next to the application.

The important part is connection configuration. Inside Compose, the database host is usually the service name, not localhost. JDBC URLs should reflect that: jdbc:postgresql://db:5432/app inside the Compose network.

This prepares developers for real deployment thinking: application configuration should be externalized, repeatable, and visible.

Where the Spring Boot workflow runs

A Spring Boot Docker workflow has two separate places: the Java build environment and the Docker runtime environment. Maven or Gradle creates the JAR from source code. Docker then packages that JAR into an image and runs it as a container.

Locally, both steps may happen on your laptop. In CI, both steps may happen on a CI runner. In production, the server should usually skip the build step and only pull the image that CI produced. This separation makes production more predictable.

Testcontainers also needs a Docker environment. When tests run locally, Testcontainers talks to local Docker. When tests run in CI, it talks to Docker available in the CI environment. If Docker is not available there, those integration tests cannot start containers.

Commands to run and inspect

Run these commands in a terminal on the machine where Docker is installed. For local learning, that is your laptop terminal. For a VPS, first connect to the server with SSH, then run the commands there. Do not paste commands blindly: run one command, inspect what changed, then run the next one.

./mvnw clean package
docker build -t spring-api:dev .
docker compose up -d db api
./mvnw test

Reference table

TopicWhat it meansPractical consequence
Executable JARRunnable Spring Boot artifactInput for the runtime image
Layered JARSeparated app/dependency layersImproves Docker cache reuse
TestcontainersReal containers in testsBetter integration confidence

Spring Boot container checklist

A useful Spring Boot image answers four questions: which JDK or JRE is used, where the JAR comes from, which port the app listens on, and how database settings are injected. If those answers are hidden, the image will be hard to operate.

For tests, use Testcontainers when the behavior depends on a real external system. Mocking is fine for service logic, but database mappings, SQL constraints, and transaction behavior need a real database sooner or later.

Checkpoint

Move on when you can describe the path from Maven or Gradle build to Docker image to Compose environment to integration test.

Practical Spring Boot exercise

Build a Spring Boot JAR, then build the Docker image twice. First change only a controller message. Then change a dependency version. Compare which build steps are reused. The lesson is that image optimization is not abstract performance work; it directly affects how fast developers and CI can validate small code changes.

Short takeaway

Main orientation for Spring Boot: the Docker image should run an already built application artifact, not become an implicit replacement for the whole build system. The clearer the path from JAR to container, the easier CI and local debugging become.