Deploying Spring Boot Applications with Docker
In the era of modern microservices and cloud-native architectures, packaging Java backend applications into images for containerized delivery has become an industry standard. As a framework designed to rapidly build standalone Spring applications, Spring Boot is naturally suited for Docker deployment. Unlike traditional virtual machine or physical server installations that require dependency packages (JAR/WAR), Docker provides a deterministic environment with "build once, run anywhere," effectively solving the classic issue of "it works on my machine" caused by operating system differences.
Before writing your Dockerfile, it is essential to understand the core concepts: an image is a packaged file containing both the application and its runtime environment; a container is an instance running based on that image; and Docker Compose allows us to orchestrate multiple services (such as applications, databases) together for deployment. Ensure you have installed Docker Desktop or Docker CE locally and can execute docker run commands correctly.
Building Spring Boot Applications with Dockerfile
Writing an optimized Dockerfile is key to successful deployment. For Java applications, we typically adopt a multi-stage build strategy to minimize the final image size: first compiling and packaging the project within a full JDK environment, then copying the generated JAR file into a lightweight base image for execution.
Here are the standard steps and example code for writing a Dockerfile:
- Select Base Image: It is recommended to use
eclipse-temurin:21-jre(OpenJDK 21) or the officially recommendedopenjdk:21-slim. These images are smaller and more secure compared to traditional Debian-based Java images. - Multi-stage Build Logic:
- Stage One: Compile and package using a toolchain with a complete JDK installed.
- Stage Two: Copy the generated JAR file into the lightweight base image.
# Define name and tag (optional)
FROM eclipse-temurin:21-jre AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn clean package -DskipTests
# Switch to a lighter base image to reduce final volume
FROM openjdk:21-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Note: When configuring the Maven plugin in pom.xml, ensure you add <skipTests>true</skipTests> to avoid excessive build time caused by test execution. Additionally, it is recommended to remove development dependencies (such as IDE support libraries) for production environments and enable JVM parameters to optimize memory usage.
Orchestrating Multi-Service Environments with Docker Compose
Deploying a single application often fails to meet real-world business requirements; middleware such as databases, caches, and message queues also require containerization. Docker Compose allows us to define configuration files for multiple services (docker-compose.yml), enabling one-click startup of an entire microservices cluster.
Through docker-compose.yml, we can declare dependencies between the Spring Boot application and MySQL/Redis:
version: '3.8'
services:
app:
build: . # Reference Dockerfile in current directory
ports:
- "8080:8080" # Map host port to container internal port
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/myapp?useSSL=false&serverTimezone=UTC
SPRING_DATA_REDIS_HOSTS: redis:6379
depends_on:
- db
- redis
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123456
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:7-alpine
This configuration enables network interconnectivity between services: the Spring Boot application accesses db and redis containers directly via environment variables without needing additional DNS configuration. During development, debug mode can be enabled (e.g., adding -Dspring.profiles.active=dev). In production environments, switch to the corresponding profile and set up security password policies.
Verifying Deployment Status and Log Monitoring Mechanisms
After construction, it is necessary to verify image correctness through actual execution. Use docker-compose up -d command to start all services in background mode; subsequently, perform health checks via the following workflow:
- Check Container Status: Execute
docker ps --format "table {{.ID}}\t{{.Names}}"to confirm that all services are running normally and in an Up state. - Access Application Interface: Request
http://localhost:8080/actuator/health(if Spring Boot Actuator is configured) via a browser or command line to check if the health result shows UP. - Real-time Log Monitoring: Use
docker-compose logs -f appto track container output, quickly locating issues such as startup failures, port conflicts, or dependency exceptions.
Furthermore, it is recommended to integrate monitoring systems like Prometheus + Grafana, exposing application metrics to Docker Exporter for visual performance analysis and alert notifications. For high availability scenarios, you can also configure multi-replica deployment strategies and auto-scaling rules (Kubernetes) to further enhance system elasticity and stability.