1. Overview
In this guide, we’ll explore how to dockerize a Spring Boot application to run it within an isolated environment called a container.
We will also demonstrate how to set up a composition of interdependent containers connected via a private virtual network. Additionally, you’ll learn how to manage these containers with simple commands.
We’ll start by creating a basic Spring Boot application and then deploy it using a lightweight base image built on Alpine Linux.
2. Dockerizing a Standalone Spring Boot Application
As an example, let’s create a Spring Boot application called docker-message-server that exposes an endpoint returning a static message:
@RestController
public class DockerMessageController {
@GetMapping(“/messages”)
public String getMessage() {
return “Hello from Docker!”;
}
}
With a properly configured Maven file, we can build an executable JAR file:
$> mvn clean package
Next, let’s run the Spring Boot application:
$> java -jar target/docker-message-server-1.0.0.jar
Now, our application is running and accessible at http://localhost:8888/messages.
To dockerize the application, create a file named Dockerfile with the following content:
FROM openjdk:17-jdk-alpine
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT [“java”, “-jar”, “/message-server-1.0.0.jar”]
Here’s what each line does:
- FROM: Specifies the base image (Alpine Linux with Java).
- MAINTAINER: Identifies the maintainer of the image.
- COPY: Copies the JAR file into the container.
- ENTRYPOINT: Defines the command to run when the container starts.
To create an image from the Dockerfile, use the following command:
$> docker build –tag=message-server:latest .
Finally, you can run the generated container:
$> docker run -p8887:8888 message-server:latest
This will start the application in Docker, making it accessible on the host machine at http://localhost:8887/messages. Note that port 8887 on the host is mapped to port 8888 in the container.
If port 8887 is already in use, choose another available port.
To manage the container (inspect, stop, or remove), use these commands:
$> docker inspect message-server
$> docker stop message-server
$> docker rm message-server
2.1 Changing the Base Image
You can easily switch to a different Java version by changing the base image. For example, to use Amazon Corretto:
FROM amazoncorretto:17-alpine-jdk
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT [“java”, “-jar”, “/message-server-1.0.0.jar”]
You can also use custom base images if needed.
3. Dockerizing Applications with Docker Compose
While Dockerfiles and individual commands are effective for creating standalone containers, managing a network of isolated applications can become complex.
Docker Compose simplifies this process by using a YAML configuration file to manage multiple containers. It allows you to start/stop a set of services with a single command and merges logs from different containers into one stream.
3.1 Adding a Second Spring Boot Application
Let’s extend our example by creating a second Spring Boot application, docker-product-server, which exposes a different endpoint:
@RestController
public class DockerProductController {
@GetMapping(“/products”)
public String getMessage() {
return “A new product”;
}
}
This application will be built and run in the same way as the docker-message-server.
3.2 Docker Compose File
We can combine the configuration of both applications into a single docker-compose.yml file:
version: ‘2’
services:
message-server:
container_name: message-server
build:
context: docker-message-server
dockerfile: Dockerfile
image: message-server:latest
ports:
– “8887:8888”product-server:
container_name: product-server
build:
context: docker-product-server
dockerfile: Dockerfile
image: product-server:latest
ports:
– “8889:8888”
depends_on:
– message-server
This file defines two services: message-server and product-server.
- context: Specifies the directory containing the Dockerfile and related files.
- ports: Maps host ports to container ports.
- depends_on: Indicates that the product-server depends on the message-server and will start after it.
To run both services, simply execute:
$> docker-compose up
This will start both containers and connect them via a private Docker network. The services can communicate using their container names, e.g., http://message-server:8888/messages.
To stop the services, use:
$> docker-compose down
4. Conclusion
By following this guide, you’ve learned how to:
- Dockerize a Spring Boot application with a simple Dockerfile.
- Use Docker Compose to manage multiple interconnected containers.
- Modify the base image for different Java distributions.
Using Docker ensures your applications are portable, isolated, and easy to deploy across various environments, whether for local development or production.