Dockerizing a Spring Boot application with MySQL database

  • June 21, 2023

In this technical article, we’re going to dive into the following topics:

  • Installing Docker engine
  • Creating a Docker network
  • Verifying Docker installation
  • Building a Spring Boot application and connecting with MySQL running in a container
  • Building a JAR via Gradle or Maven
  • Configuring a Dockerfile
  • Building a Docker image
  • Running the Docker image

Installing Docker engine

Installing Docker Engine

  • Follow the installation process until installation is complete.
  • After completion of the installation click Close.
  • Start the docker desktop engine from the shortcut menu.

Creating a Docker network

A Docker network is a collection of containers running together. A Docker network is used to provide complete isolation to containers.

  • To create a docker network type the following command:
docker network create <network-name>

Creating a Docker Network

  • To see all available networks, type the following command:
docker network ls

Creating a Docker Network

Verifying Docker installation

Verifying the Docker installation, pulling the MySQL image from DockerHub, and running it.

  • To pull MySQL’s docker image type the following command in the terminal:
docker pull MySQL

Verifying Docker Installation

  • To run the pulled image type the following command:
   docker run --name <mysql-container-name>
--network <network-name>
-p <host-machine-port>:<mysql-server-port-in-container>
-e MYSQL_ROOT_PASSWORD=<root-user-new-password>
-d mysql

Verifying Docker Installation

–name: It is used to specify a specific name for a container; otherwise, Docker Engine will assign a unique name itself.

–network: It is used to define a Docker network on which our container will be deployed. Networks help in achieving total isolation of containers.

-p: It is used to perform port mapping between our host machine and the container, where <host-machine-port> represents the port through which we will interact with our host machine. All requests made to <host-machine-port> will be forwarded to <mysql-server-port-in-container> within the container.

-e: It is used to pass an environment variable. In this case, we will be passing a new password for the root user.

-d: It is used to run containers in detached mode, so that our container is not terminated when the terminal is closed.

  • To connect to the database in the container, open MySQL Workbench and connect to localhost:<host-machine-port>. Then, enter the password assigned to the root user.

Verifying Docker Installation

  • Create a new database named ‘poc’. We will use this database in our application.

Verifying Docker Installation

Building a Spring Boot application and connecting with MySQL running in a container:

We will create a REST API with a single endpoint only to save users in the database.

  • To create a new Spring Boot project go to https://start.spring.io/
  • Now configure project type (Gradle or Maven), Spring Boot version, metadata and Java version according to your need.
  • Add following dependencies:
    • Spring Web
    • Spring Data JPA
    • MySQL Driver
  • Generate and download the project.

Building a Spring Boot Application

Now we will make the following changes to our application:

  • Create an Entity class “user” with basic information.
  package com.apisero.microservice.entities;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String email;
    private String name;
    private int age;

    public User() {
    }

    public User(int id, String email, String name, int age) {
        this.id = id;
        this.email = email;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • Now let’s create a repository to interact with the database.

Building a Spring Boot Application

  • Now let’s create a RestController to give endpoints to our REST API.

Building a Spring Boot Application

  • Add the following database configuration to the application.properties file:
spring.datasource.url=jdbc:mysql://localhost:3309/poc

spring.datasource.username=root

spring.datasource.password=Apisero@123

spring.jpa.hibernate.ddl-auto = update

spring.jpa.show-sql=true

Building a Spring Boot Application

  • Now we will run our application and make a call to endpoint ‘POST: localhost:8080/users’.

Building a Spring Boot Application

Building a JAR via Gradle or Maven:

Before building the jar, we need to update the application.properties file because till now we are able to access localhost:3309 on the host machine, But on containerization of our application, port 3309 on the host machine will not be accessible, since localhost in the container will point to the container itself, thus we need to modify our datasource in application.properties file.

Update spring.datasource.url to jdbc:mysql://<mysql-container-name>:3306/poc

Building a JAR via Gradle or Maven

1. Building Jar via Gradle:

Go to the root of your project and run the following command:

gradle clean build jar

Building Jar via Gradle

Gradle will generate a jar file in ‘./build/libs/’

Eg: ‘./build/libs/microservice-0.0.1-SNAPSHOT.jar’

2. Building Jar via Maven:

Go to the root of your project and run the following command:

mvn clean package

Building Jar via Maven

Building Jar via Maven

Maven will generate a jar file in ‘./target/’ folder

Eg: ‘./target/microservice-0.0.1-SNAPSHOT.jar’

Configuring a Dockerfile:

Create a file named “Dockerfile” in the root or any subdirectory of the project and write the following configuration code.

FROM openjdk:17
COPY /path/to/generated/jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Configuring a Dockerfile

FROM: It will create a layer from an existing Java image from any container registry.

ADD: It will copy files from the source and add them to the filesystem of the image at the provided path (usually second argument).

ENTRYPOINT: It specifies the command that Docker will use to run our app. In this case we will pass [“java”, “-jar”, “<name-of-the-jar>”]

Building a Docker image:

To Build a docker image type the following command. (Don’t add the name “Dockerfile” to the path):

docker build --tag <image-name>:<image-tag> ./path/to/Dockerfile

Building a Docker Image

To see the newly created docker image type the following command:

docker image ls

Running the Docker Image

Running the Docker image:

To run a docker image run the following command:

  docker run
-network <network-name>
-p <host-machine-port>:<application-port>
-d <image-name>

Here -p is used to do port mapping between the <host-machine-port> and <application-port>. where <host-machine-port> is the port number on the host system which we will use to interact with the container and <application-port> is the port within the container on which our application is running.

All requests made to <host-machine-port> will be forwarded to the <application-port> in the container.

–network is used to define the docker network, on which our container will be deployed, network is required for the complete isolation of our docker container.

-d is used to run containers in detached mode, So our container is not killed upon closing the terminal.

Running the Docker Image

Now, we’ll make a call to the endpoint ‘POST: localhost:9090/users’

Running the Docker Image

As we can observe, calls are now being made on port 9090 instead of the original port 8080, which indicates that our application has been successfully dockerized. However, if we check the Spring startup logs in the terminal, it states that the application started on port 8080 because the application was originally running on port 8080 within the container.

— By Sudhanshu Jha