Docker
If you've been doing software development for a bit, you've likely seen this logo:

Docker is like a standard shipping container for software. Just as shipping containers revolutionized global trade by providing a standard way to transport goods regardless of content, Docker provides a standard way to package and run software regardless of the underlying infrastructure.
Think of Docker as creating a complete, self-contained box that has everything your application needs to run:
- The application itself.
- All libraries and dependencies.
- Runtime environment.
- Configuration.
This "box" (called a container) can then be moved and run consistently on any system that supports Docker * from a developer's laptop to a test environment to a production server.
Why Dockerize Spring Boot Applications?
Spring Boot applications are perfect candidates for Docker containers for several reasons:
- Portability across environments.
- Docker containers bundle the application along with all its dependencies (e.g., JDK, libraries).
- It ensures consistency across different environments (development, staging, production), avoiding the classic “it works on my machine” problem.
- Ease of deployment.
- A Docker image is a self-contained artifact that can be deployed anywhere Docker is supported (on-premises, AWS, GCP, Azure, etc.).
- Scalability.
- Containers are lightweight compared to traditional virtual machines, allowing you to spin up multiple instances of your Spring Boot app quickly.
- Useful for microservices architecture where scaling individual services is common.
- Isolation.
- Each Docker container runs in its own isolated environment.
- This avoids conflicts between your Spring Boot app’s dependencies and other apps or system-level libraries.
- Simplified CI/CD pipelines.
- Docker integrates seamlessly with CI/CD tools like Jenkins, GitLab CI, or GitHub Actions.
- Improved resource utilization.
- Containers share the host OS kernel, making them more resource-efficient than traditional VMs.
- This enables running more instances of your Spring Boot app on the same hardware.
- Versioning and rollbacks.
- Docker images are versioned, allowing you to track changes and roll back to a previous version if needed.
- Cloud-Native alignment.
- Most cloud platforms are optimized for containerized applications.
- Simplifies team collaboration.
- Developers and DevOps teams can use the same Docker image to ensure that everyone is working with identical application setups.
Dockerfile for Spring Boot
A Dockerfile
defines how your Spring Boot application should be containerized. Here's my own implementation:
# Build Stage
FROM gradle:jdk21-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build -x test --no-daemon
# Run Stage
FROM eclipse-temurin:21-jre-alpine
RUN apk add --no-cache curl
COPY --from=build /home/gradle/src/build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
Nonetheless, if you are joining a team that already have their own Dockerfile
defined, is best to avoid modifications unless necessary.
Understanding the Multi-Stage Build
This Dockerfile
uses what's called a multi-stage build:
Build Stage. This first stage is like a workshop where we build our application:
- We start with a container that has Gradle and the full Java Development Kit (JDK).
- We copy our Spring Boot project into this container.
- We run the Gradle build command to compile our application and create a
JAR
file. - When done, we'll have our compiled application, but also a lot of build tools we don't need anymore.
Run Stage. This second stage is the actual container that will run:
- We start with a much smaller container that only has the Java Runtime Environment (JRE).
- We add curl for health checks and troubleshooting.
- We copy just the final
JAR
file from the build stage. - We set up the command to run our application.
Benefits of This Approach
This two-stage approach provides several advantages:
- Smaller final image size: The final container only includes what's needed to run the application, not to build it.
- Better security: Fewer components mean fewer potential vulnerabilities.
- Faster deployments: Smaller images deploy more quickly.
- Cleaner separation: Build concerns are separated from runtime concerns.
Now I Should Build the Container Right?

While building and testing Docker images locally is the ideal scenario, in many professional environments, developers take a different approach:
Docker Installation Challenges
Getting Docker running smoothly on your development machine isn't always straightforward:
- Windows users may face compatibility issues with WSL (Windows Subsystem for Linux), Hyper-V requirements, or performance concerns.
- macOS users need to work with Docker Desktop, which consumes significant system resources and has licensing requirements for larger organizations.
- Linux users have the most native experience but still need proper permissions and configuration.
These setup hurdles can distract from your primary job: writing code.
Leveraging Existing Pipelines
Most established projects already have CI/CD pipelines configured:
- When you push code to the repository, automated processes build, test, and deploy your changes.
- Development and test environments are automatically updated with your changes.
- Build logs and deployment results are available through your CI/CD platform (Jenkins, GitHub Actions, GitLab CI, etc.).
In these cases, it's often more efficient to:
- Push your changes to a feature branch.
- Let the pipeline handle the Docker build process.
- Review logs if issues occur.
- Check the deployed application in the development environment.
This approach lets you focus on code quality while specialized pipeline tools handle the build process in consistent, controlled environments purpose-built for that task.
Why Every Developer Should Understand Docker Basics
- Troubleshoot deployment issues by understanding container logs and behaviors.
- Collaborate effectively with DevOps teams using shared terminology.
- Create consistent environments across development and production.
- Write more portable code that doesn't rely on specific machine configurations.
- Advance your career with a skill now considered fundamental in modern development.
Understanding Docker helps bridge the gap between "it works on my machine" and "it works everywhere" – essential knowledge in today's containerized world.
Recommended Learning Resource
I really recommend KodeKloud's video "Learn Docker in 2 Hours—A Full Tutorial (2025)".