BookStore Docker 3 : Dockerlize Spring Application & Connect to MySQL Container Only With Dockerfile

Byung Joo JeongByung Joo Jeong
10 min read

This document goal is to Dockerize Spring Application & Connect to MySQl Container.

Docker Reference Link

Docker Basic

: https://joo.hashnode.dev/book-store-docker-1-docker-basic-with-process-of-creating-image-and-container

MySQL Monitoring With Docker

Reference Link : https://joo.hashnode.dev/book-store-docker-2-mysql-monitoring

3 Key Terms for Docker

1.Docker Container - Role of Virtual Machine

  • Docker container is like a Virtual Machine.

  • It is an executable package that includes everything needed to run software.

  • everything that needs to run software include includes code, runtime, system tools, libraries, and setting.

2.Docker Image - Blueprint for Creating Container

  • A Docker image is a read-only template.

  • It's acting as a blueprint for creating a Docker container.

  • It includes application code, libraries, dependencies, and other necessary files.

3.Dockerfile - Recipe for Creating Docker Image

  • A Dockerfile is a text file.

  • It contains commands and instructions to build Docker image.

  • It specifies the image to use, application files to copy, dependencies to install, and commands to run.


Prerequisite

Step 1.Create Docker Container for MySQL

  • Pull the MySQL Image

  • Run(create) a MySQL Container

  • Verify MySQL Container

Link : https://joo.hashnode.dev/book-store-docker-1-docker-basic-with-process-of-creating-image-and-container

I used application.yml and .env file configuration.

Link : https://joo.hashnode.dev/bookstore-spring-env-file-setup-env-configuration-with-applicationyml


Dockerlize Spring Boot Application

Step 3: Dockerize the Spring Boot Application

1. Create a Dockerfile in Spring Boot Root Directory.

Create a file named Dockerfile with the following content:

Root Directory -> Create Dockerfile -> add below content.

Dockerfile configuration

# Use the official OpenJDK image as a parent image (Base Image)
FROM openjdk:17-jdk-alpine
#Base Image: openjdk:17-jdk-alpine provides a lightweight environment with JDK 17.

# Set the working directory in the container
WORKDIR /app
# Working Directory: /app is set as the working directory inside the container.

# Copy the JAR file into the container
COPY build/libs/BookStore-0.0.1-SNAPSHOT.jar app.jar
# Copy JAR: Copies the built JAR file from the build/libs directory into the container.
# 'app.jar' in the Dockerfile is a way of renaming the JAR file inside the Docker image to a consistent name.

# Expose the port that the application runs on
EXPOSE 8080
# Expose Port: Exposes port 8080, which is the default port for Spring Boot applications.

# Define the command to run the application
ENTRYPOINT ["java", "-jar", "app.jar"]
# Run Command: Uses java -jar to run the JAR file.


----------------------------------------------------------------
#----- You can replace COPY & ENTRYPOINT with below
#COPY build/libs/BookStore-0.0.1-SNAPSHOT.jar app.jar
#ENTRYPOINT ["java", "-jar", "BookStore-0.0.1-SNAPSHOT.jar"]

Before building docker image,

gradle : clean & build

./gradlew clean

./gradlew build

or

Step 4:Verify 'Jar' file has been created

  1. Check file directory

After running these commands, verify that the JAR file has been created in the build/libs directory. The JAR file should have a name similar to

bookstore-0.0.1-SNAPSHOT.jar.

BookStore-0.0.1-SNAPSHOT.jar

or use the command

ls build/libs/

Step 5. Build Docker Image

docker build -t spring-bookstore .

Command Breakdown

  1. docker build
  • build a docker image from a Dockerfile
  1. -t spring-bookstore
  • -t flag tag : is used to specify a tag for the image, which should be lowercase

  • spring-bookstore : the name of image you are creating, tag is lowercase, this also should be lowercase. (we can use spring-bk, which means you can set the name.)

Build Success!


Step 6. Verify Docker Image

Verify that the image has been created successfully by listing all Docker images:

docker images

  • I have 2 Docker Images including mysql image

  • we can see spring-bookstore docker Image on REPOSITORY (I created atm)

Step 7. Run & Create the Spring Container

Run a container from the image you just built. This will start your Spring Boot Application inside a Docker container.

docker run -d -p 8080:8080 --name spring-bookstore-container spring-bookstore

Command Breakdown

-d

  • Run the container in detached mode.

  • Detached mode allows the container to run in the background.

  • Docker Container starts and runs independently of your teminal session.

  • You don't need to keep the terminal open to keep the container running.

-p 8080:8080

  • This allows you to access the application running inside the container on the port 8080 of your host machine.

  • The first '8080' refers to the port on your host machine.

  • The second '8080' refers to the port on the Docker container.

--name spring-bookstore-container: Assign a new name to the running container, in other words, it's naming your running container.

spring-bookstore: The name of the Docker image you just built.

+Host Machine & Local Machine & Docker Container?

Host Machine

  • Physical or Virtual Machine , where the Docker service (daemon) is runing.

  • In my case, It's Docker Desktop (window)

    ->It's machine to manage and run Docker Container.

Local Machine

  • Generally it refers to your computer you are currently using.

Docker Container :

If you are running Docker Container on your personal laptop or destop

  • Your computer is the host machine.

  • Host Machine is where Docker is installed and running.

  • Local Machine is the machine you are currently working on.

In conclusion,

  • In many cases, especially during development, your local machine == host machine

+Detatched Mode in Docker

Simply put, running a container in detatched mode lets you use your terminal and Docker commands freely while your container continues to run in the backgroud.

  • Background Process: The container runs as a background process.

  • Terminal Free: You get back your terminal prompt immediately after running the command.

  • Monitoring: You can still monitor and manage the container using Docker commands like docker ps, docker logs, docker stop, etc.

While you run the docker container, you can still use the following commands

docker ps

After docker runs, I used docker ps

docker logs spring-bookstore-container


Step 8. Check the status of Running Containers

Before we begin,

check the status ofDocker Images & Docker Containers

docker images

docker ps to check running containers.

docker ps

Run mysql container & spring-bookstore-container

Start spring-bookstore-container

docker start spring-bookstore-container

Start mysql-container

docker start mysql-container

To see all status for Docker : images, Container name, ports, including stopped.

docker ps -a

: using docker ps -a we can see all containers, Images

1.Create A New Docker Bridge Network

Create a user-defined bridge network to allow the containers to communicate.

docker network create bookstore-bridgenetwork

2.Check All Docker Networks:

docker network ls

2.Connect both containers to new network

: Ensure your both containers are running

Connect the MySQL Container to New Bridge Network you defined:

docker network connect bookstore-bridgenetwork mysql-container

Connect the Spring Boot Container to New Bridge Network you defined:

docker network connect bookstore-network spring-bookstore-container

3. Inspect a Bridge Network to check the connection

: To get detailed information about a specific network, including its configuration and connected containers, use the docker network inspect command followed by the network name or ID.

docker network inspect bookstore-bridgenetwork

This command will output detailed JSON information about the specified network, including its name, subnet, gateway, and a list of connected containers.

You can see "Containers" data that include mysql-container & spring-bookstore-container.

From the 'docker network inspect' output

4. Check Network Connectivity :

Verify that your containers can communicate with each other. You can use docker exec to access a container and ping the other container by name.

docker exec -it spring-bookstore-container ping mysql-container

(you can use ctrl + c to stop)

The ping statistics

luaCopy code--- mysql-container ping statistics ---
11 packets transmitted, 11 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.114/0.171 ms

All packagets were successfully received (0% package loss)

  • This means that the connectivity between my container (spring) and MySQL container is stable

Round-trip times

  • with minimum of 0.072ms , an average of 0.114ms, a maximum of 0.171ms

  • This means Round-trip times is very low, times are excellent, which indicate "very quick Response" from MySQL Container.

Step 10. Verify You can access 8080 Port

docker ps -a 
docker ps

1.Check Docker Container

  • docker ps command can show you currently running container, while docker ps -a shows all containers, including those that are stopped.

2.Port Mapping

  • Since 'spring-bookstore-container' is mapped to '0.0.0.0:8080->8080/tcp', you can access 'localhost:8080' on your host machine (your computer)

  • Simply put, spring-bookstore-container is running on 8080 port, which means you can access localhost:8080 port.

I added Spring Security dependency, so I can see Login form, which confirms that Spring Boot Application is running correctly.

3.When the container is stopped (+ embedded Tomcat & Spring Container)

Spring Boot container runs the Spring Boot application, which includes an embedded Tomcat server. The Tomcat handles incoming web request on port 8080 within the container (Process I've done is for this.)

  • Spring Boot Container: This container runs your Spring Boot application.

  • Embedded Tomcat Server: By default, Spring Boot applications use an embedded Tomcat server to handle web requests.

  • Default Port 8080: The Spring Boot application listens on port 8080 within the container.


Key details of

docker network inspect bookstore-bridgenetwork:

  • it's clear that the bookstore-network has two containers connected:

  • mysql-container with IP address 172.18.0.2

  • spring-bookstore-container with IP address 172.18.0.3

Simply put, Bridge Network Is

  • In Docker, a Bridge Container is a user-defined network that allows different containers to communicate with each other.

When containers are connected to the same bridge network, To summarize

  • Bridge Network: A virtual network that enables communication between containers on the same Docker host.

  • Use Case: Ideal for scenarios where containers need to interact with each other directly but are isolated from containers outside of the network.


Trouble Shooting

Error whlie building Docker Image

The command docker build -t spring-book-store . is used to build a Docker image from a Dockerfile located in the current directory.

1.ERROR : Build Docker Image Without Docker Desktop

\==> I didn't run the Docker Desktop => Resolve : Run Docker Desktop

2.Dockerfile Wrong Configuration

:Issue With pulling the openjdk:17-jre-slim image.

docker search openjdk

PS D:\GitClone_FC\Joo_BookStore_FullStack_20240725\BookStore\BookStore> docker search openjdk
NAME                                    DESCRIPTION                                     STARS     OFFICIAL
openjdk                                 Pre-release / non-production builds of OpenJ…   3935      [OK]
eclipse-temurin                         Official Images for OpenJDK binaries built b…   573       [OK]
sapmachine                              Official SapMachine Docker Image, SAP's buil…   51        [OK]
ibm-semeru-runtimes                     IBM Semeru Runtimes Official Images for Open…   46        [OK]
circleci/openjdk                        CircleCI images for OpenJDK                     11
cimg/openjdk                            The CircleCI OpenJDK (Java) Docker Convenien…   8
bellsoft/liberica-openjdk-debian        Liberica is a 100% open-source Java implemen…   27
bellsoft/liberica-openjdk-alpine        Liberica is a 100% open-source Java implemen…   58
bellsoft/liberica-openjdk-centos        Liberica is a 100% open-source Java implemen…   4
bellsoft/liberica-openjdk-alpine-musl   Liberica is a 100% open-source Java implemen…   24
datastax/ds-base-debian-openjdk-8                                                       1
balenalib/fincm3-alpine-openjdk         This image is part of the balena.io base ima…   1
balenalib/artik10-alpine-openjdk        This image is part of the balena.io base ima…   0
balenalib/armv7hf-alpine-openjdk        This image is part of the balena.io base ima…   1
balenalib/artik5-alpine-openjdk         This image is part of the balena.io base ima…   0
balenalib/amd64-alpine-openjdk          This image is part of the balena.io base ima…   0
balenalib/amd64-openjdk                 This image is part of the balena.io base ima…   0
balenalib/aarch64-alpine-openjdk        This image is part of the balena.io base ima…   0
balenalib/artik530-alpine-openjdk       This image is part of the balena.io base ima…   0
balenalib/raspberrypi3-alpine-openjdk   This image is part of the balena.io base ima…   3
balenalib/parallella-alpine-openjdk     This image is part of the balena.io base ima…   0
balenalib/qemux86-openjdk               This image is part of the balena.io base ima…   0
balenalib/intel-nuc-fedora-openjdk      This image is part of the balena.io base ima…   0
balenalib/aarch64-openjdk               This image is part of the balena.io base ima…   0
balenalib/amd64-debian-openjdk          This image is part of the balena.io base ima…   0

Resolve : Use OpenJDK Base image (parent image)


Error : Jar File configuration is wrong in Dockerfile

ERROR [3/3] COPY build/libs/bookstore-0.0.1-SNAPSHOT.jar app.jar

Resolve: Jar file name that alines with /build/libs built'Jar'

As you see, BookStore/build/libs/BookStore-0.0.1-SNAPSHOT.jar

But, Dockerfile -> COPY build/libs/bookstore-0.0.1-SNAPSHOT.jar app.jar

That should be like this :

COPY build/libs/BookStore-0.0.1-SNAPSHOT.jar app.jar


Error (Command, Directory name should be lowercase.)

Resolve : right command with lowercase


I can't see the spring-bookstore-container on Docker Desktop

and I have image, but.. I can't see the container.

Even though I removed and recreated the container / restart docker, still there's no spring-bookstore-container.

Remove and Recreate the Container:

# Stop and remove the existing container
docker stop spring-bookstore-container
docker rm spring-bookstore-container

# Run a new container with port mapping and a name
docker run -d -p 8080:8080 --name spring-bookstore-container spring-bookstore

Still I can't see.

Later, if I know how to handle this, I will update.


Oh my,,, super idiot

I used filter.

Without filter, I can see both containers.

0
Subscribe to my newsletter

Read articles from Byung Joo Jeong directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Byung Joo Jeong
Byung Joo Jeong