Spring Boot Deploy on Docker

Spring Boot can be deployed on Docker with a jar file integrated with Dockerfile and Docker Compose. The developer can pack a jar file and deploy it on Docker. Docker provides feature deployment through Dockerfile and Docker Compose, which help developers deploy applications quickly and manage multiple application clusters, such as microservices.

The developer can read more about creating a Spring Boot application.

For example, IntelliJ is used to create files and manage projects.
IntelliJ provides plugins to support deploying Spring Boot applications to Docker.

Read more about IntelliJ plugins.

For Docker GUI, using Docker Desktop to manage Docker helps the developer quickly learn about the Docker concept and become familiar with it. Docker Desktop supports macOS, Windows, and Linux.

Read more about and download Docker Desktop.

Docker Desktop

Spring Boot project directory structure.

/workspaces/demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── demo/
│   │   │               ├── DemoApplication.java
│   │   │               ├── controller/
│   │   │               └── service/
│   │   ├── resources/
│   │       ├── application.properties
│   │       └── static/
│   └── test/
├── target/
├── Dockerfile
├── docker-compose.yml
├── pom.xml
└── README.md

For example, build a jar file.

Execute the command to create a jar file in the project directory.

cd D:\workspaces\demo
mvn clean package -DskipTests

A jar file has been created in the target folder.

For example, create an image from a jar file.

Create the DockerFile named “DockerFile” in the root of the project directory.

The developer can install plugins to support the Dockerfile to identify and validate the structure.

# Use a base image with Java installed
FROM openjdk:21

# Set the working directory in the container
WORKDIR /app

# Copy the JAR file into the container at /app
COPY target/*.jar app.jar

# Specify the command to run your application
CMD ["java", "-jar", "app.jar"]

Execute the command line to create an image on Docker.

docker build -t demo-myapp .

Check if an image was created.

docker images

REPOSITORY       TAG       IMAGE ID       CREATED             SIZE
demo-myapp       latest    6f34bf16b0e9   About an hour ago   636MB

The images have been created and are ready to deploy. Execute the command line to deploy the image to the container.

docker run -d -p 8080:8080 --name myapp-container demo-myapp

The developer can stop an application using the shortcut Ctrl+C.

Alternatively, the developer can run the Docker command to run the application in the background process.

docker run -d -p 8080:8080 --name myapp-container demo-myapp -d

When the developer runs the command in the background, it closes the terminal. The application will not stop.

Check the container in which applications are deployed.

docker container ls
CONTAINER ID   IMAGE            COMMAND                  CREATED       STATUS       PORTS                           NAMES
246b973734dc   demo-myapp       "java -jar /app.jar"     2 hours ago   Up 2 hours   0.0.0.0:8080->8080/tcp          myapp_container

The Docker container displays information about the applications inside it.

For example, create a jar file and an image in a Dockerfile.

The Dockerfile provides a feature to create a jar file from a project using Apache Maven. The developer can build a jar file in a Dockerfile.

Create a Dockerfile with a create a jar file and build an image.

# Stage 1: Build the JAR file
FROM maven:3.9.7-amazoncorretto-21 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Run the application
FROM openjdk:21
VOLUME /tmp
EXPOSE 8080
COPY --from=build /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Execute the command line to create a jar file and then create an image on Docker.

docker build -t demo-myapp .

Check if an image was created.

docker images
REPOSITORY       TAG       IMAGE ID       CREATED       SIZE
demo-myapp       latest    344bdb7dd3b4   2 hours ago   636MB

The Docker shows information about the image, such as tag, image ID, and size.

Execute the command line to deploy the image to the container.

docker run -d -p 8080:8080 --name myapp-container demo-myapp -d

Check the container in which applications are deployed.

docker container ls
CONTAINER ID   IMAGE            COMMAND                  CREATED       STATUS       PORTS                           NAMES
246b973734dc   demo-myapp       "java -jar /app.jar"     2 hours ago   Up 2 hours   0.0.0.0:8080->8080/tcp          myapp_container

The developer can check if an application has started by viewing logs.

docker logs myapp-container

Deploy Spring Boot on Docker with Docker Compose

Create docker-compose.xml in the project directory.

services:
  myapp:
    image: myapp:1.0.0
    build:
      context: .
      dockerfile: Dockerfile
    container_name: myapp_container
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: docker
      SPRING_DATASOURCE_URL: jdbc:postgresql://172.20.0.2:5432/demo
      SPRING_DATASOURCE_USERNAME: admin
      SPRING_DATASOURCE_PASSWORD: password
    networks:
      postgres_postgres-network:
        ipv4_address: 172.20.0.4
networks:
  postgres_postgres-network:
    external: true

In the Docker Compose file, use the postgres_postgres-network network because the Spring Boot application inside Docker must use the same network to connect to the database.

In the environment, the attribute can override the config from application.properties.

The developer can control the version of an application by using an “image” attribute <app_name>:<tag_name>

Execute the command line to deploy the Spring Boot application to Docker.

docker compose up

Check if an image was created.

>docker images
REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
myapp            1.0.0     223aaea0bcc6   20 minutes ago   636MB

Check the container in which applications are deployed.

CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS             PORTS                           NAMES
d84c729e6857   myapp:1.0.0      "java -jar /app.jar"     28 minutes ago   Up 28 minutes      0.0.0.0:8080->8080/tcp          myapp_container

The developer can stop and remove the running containers, along with any networks created by the ‘up’ command.

docker compose down

Reduce Docker image size.

The developer faces the problem of enormous image size—the size of a Docker image from a jar file and the JDK. The developer can reduce the size of the Docker image by reducing the size of the jar file and changing OpenJDK.

Reduce the size of a jar by removing unused libraries.

Modifiy Dockerfile for change OpenJDK.
Change from openjdk:21 to amazoncorretto:21-alpine.

# Stage 1: Build the JAR file
FROM maven:3.9.7-amazoncorretto-21 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Run the application
FROM amazoncorretto:21-alpine
VOLUME /tmp
EXPOSE 8080
COPY --from=build /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Check the image size after changing the OpenJDK.

>docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
myapp            1.0.0     337af59f4fbf   7 minutes ago   449MB

The size of the Docker image was reduced from 636 MB to 449 MB. The developer can find OpenJDK through a suitable link for the project.

Regain disk space from the build cache.

When the developer builds the image multiple times, Docker retains the build cache, consuming disk space. The developer can remove the build cache to clean the Docker disk space.

docker builder prune

Or a specific time.

docker builder prune --filter=until=24h

Docker will remove the build cache to regain disk space.

>docker builder prune
WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
ID                                              RECLAIMABLE     SIZE            LAST ACCESSED
tu4xgu6uncnf7lic40k1vudsg                       true            67.48MB         23 minutes ago
zesq2ddqempaztc5v4dmysutt*                      true    301.5MB         2 days ago
yqism4du5o6aar05qfs6frf56*                      true    99.63MB         17 minutes ago
1nao14f7mfic6rckq57pekqin*                      true    99.68MB         15 minutes ago
136upuos04ueg86698onqfz7x*                      true    98.45MB         18 minutes ago
1r6c6m5fi20dgwwhtxujpat9b                       true    131.8MB         2 days ago
vkmh4r9kr6uy9giqqu646a556*                      true    301.5MB         9 minutes ago
7t0xioew522nkpan7o7rbe3w2*                      true    96.63MB         20 minutes ago
41lk2v46fkdilxzcptnt68mr7                       true    99.63MB         17 minutes ago
pujsd6l5s7b47crgdogw8sc9i                       true    98.45MB         18 minutes ago
7ake92a5q8ccrl0ugkzj2egno                       true    131.8MB         2 days ago
ie3t256s7ipvjliwcekb5rzj5                       true    131.8MB         9 minutes ago
fanmm3qv2td7iin35es3dyj8w                       true    95.49MB         21 minutes ago
qaahv3dusdm5vyrt1hwchm8nz*                      true    67.48MB         23 minutes ago
r3iesxlco2iax1q04pm09n6xe                       true    96.63MB         20 minutes ago
36d9q7yhqoa7308f7z8e0psg6                       true    117.9kB         Less than a second ago
mapvhmejjxmfnbpelon93oo2p                       true    117.9kB         2 hours ago
wgklx2mlwhb446jy9oa6pndwt                       true    131.8MB         2 hours ago
ktkjpo4qlzclk62h3jado4k7c*                      true    0B              9 minutes ago
xht8tgnck2jr2pwgib2csunfs                       true    131.8MB         47 minutes ago
gh27uf7lzyxygjtmkl36zyy90                       true    0B              47 minutes ago
ofd75ozsowyrg53rsgn638x2q*                      true    301.5MB         2 days ago
zq13t0q4qqndhszo1kdrs4gmh*                      true    318B            9 minutes ago
jv877s2g4oojx75hgxz2si19m*                      true    124.1kB         9 minutes ago
4od7l5iq5zqyx2edrys9a3p06                       true    99.67MB         15 minutes ago
24t28fyhbjkgqvbo23bpisc5m*                      true    95.49MB         21 minutes ago
v17p3e7yx8xq14xfst2pl1o19                       true    131.8MB         15 minutes ago
q4ctv7065iycz8g6xm2t9n5e1                       true    0B              47 minutes ago
c9jl3hd0fa3i2nz46b98k8pxf                       true    0B              Less than a second ago
540kiz4ttwocoj7l5fhn3bw84                       true    117.8kB         Less than a second ago
m4kf1nvaqeygcjm6k8wb6tndc                       true    0B              Less than a second ago
td05cq5mgzl1awbh2urlwcp0m                       true    6.319kB         Less than a second ago
vnao9xckt7jty3rpcp73x7s9q                       true    0B              23 minutes ago
ar41xz1odrpeh0313j4o3z9fc                       true    0B              Less than a second ago
z3s9jy3aj4xj43q2bvwnw81ol                       true    0B              9 minutes ago
piul44hdxunnjo5lwdxjl3ki0                       true    0B              Less than a second ago
lilk5cwngipo0hl038xuhmzr5                       true    0B              Less than a second ago
i2rz2rdxix3dwqambmuiqlw2u                       true    0B              23 minutes ago
rw5y19yqqniqzn733bkif7taa                       true    0B              Less than a second ago
qllnpgsz47ozsnjhdn2geil5r                       true    0B              23 minutes ago
f6ah0lfwwuql235byxze728qr                       true    0B              Less than a second ago
w8vfc9pedlfmvn6gh0bxp7rza                       true    0B              Less than a second ago
69427u9yuc1x3nettgrhpz622                       true    0B              Less than a second ago
jywrb9h68niooq37oisxzynzv                       true    0B              Less than a second ago
9njysdc8ultvus3f1s03s1wqn                       true    0B              Less than a second ago
Total:  2.811GB

Finally

Docker helps developers quickly manage and deploy applications. It provides various features for managing Docker.
The developer should learn Docker to communicate with DevOps and design the CI/CD pipeline for the software architecture. The developer can use Docker, integrated with Docker Swarm or Kubernetes, to enhance the deployment, management, and scalability of containerized applications.

Leave a Comment

Your email address will not be published. Required fields are marked *