Dockerizing a Spring boot Application with MySQL Database

Dockerizing a Spring boot Data JPA Application with MySQL Database

Here we are going to deploy Spring boot with MYSQL application on AWS EC2 (Ubuntu) instance. So before to that we need to adhere to pre-requisites of installing Java , Git and maven

We will have two docker containers ,

      Container 1: One for hosting MYSQL database i.e. Database server .

      Container 2: One for hosting Spring boot application i.e. Web/Application server . Spring boot application has embedded tomcat                                          server  for our deployment.

Before going to dokerize our web application , we need to first create a MYSQL database server. So you need to visit below link in order to Create MYSQL database docker container.

Once the database server is up and running , we will create separate container for our spring boot web application following below steps –

 

Step 1:  Download the application to be Dockerized

Create folder docker under /usr/docker

sudo mkdir docker

Then cd into it –

cd /usr/docker

Then download application source code from repository to local system. Here in our case we have git repository.

sudo git clone https://github.com/AnupBhagwat7/TodoListManagerJPA_Docker.git

This is a spring boot application connecting MYSQL database through data JPA .

Step 2: Change the application.properties file

Change the application.properties file to point to the MYSQL database server which we created earlier .

spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
server.port=8081

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://mysql-dev-server:3306/testdb
spring.datasource.username = test
spring.datasource.password = test

## Hibernate Properties

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

server.error.whitelabel.enabled=false

Step 3: Maven clean and package the application 

 cd TodoListManagerJPA_Docker/

mvn clean package 

Step 4:  Define a docker image with Dockerfile

touch Dockerfile

Dockerfile is where we define the docker image and specify all the configurations required to run the app. Following is the Dockerfile for our spring boot application –

# Start with a base image containing Java runtime
FROM openjdk:8-jdk-alpine

# Add Maintainer Info
LABEL maintainer="[email protected]"

# Add a volume pointing to /tmp
VOLUME /tmp

# Make port 8081 available to the world outside this container
EXPOSE 8081

# The application's jar file
ARG JAR_FILE=target/TodoListManagerJPA_Docker.jar

# Add the application's jar to the container
ADD ${JAR_FILE} TodoListManagerJPA_Docker.jar

# Run the jar file
ENTRYPOINT ["java","-jar","/TodoListManagerJPA_Docker.jar"]

FROM openjdk:8-jdk-alpine – A docker image can use another image available in the docker registry as its base or parent image. In the above example, we use the openjdk:8-jdk-alpine image as our base image.

LABEL maintainer – The LABEL instruction is used to add metadata to the image. In the above Dockerfile, we have added some info about the maintainer of the image through LABEL instruction.

VOLUME: Volumes are a mechanism to persist data generated by the container on the Host OS, and share directories from the Host OS with the container.

You can mount a VOLUME with path /var/log in the Dockerfile, and then specify the directory on the Host OS to which this mount point will be mapped to while running the container. After that, you’ll be able to access the logs from the mapped directory on the Host OS.

In the above Dockerfile, we created a mount point with path /tmp because this is where the spring boot application creates working directories for Tomcat by default. Although it’s not required for this spring boot application because who cares about tomcat directories. But if you want to store stuff like tomcat access logs, then VOLUMES are very useful.

EXPOSE: As the name suggests, this instruction allows you to expose a certain port to the outside world. You can skip this step as we are going to user -p option while running the image for mapping the docker container port with host machine’s port.

ARG: The ARG instruction defines a variable with a default value.

ADD: The ADD instruction is used to copy new files and directories to the docker image.

ENTRYPOINT: This is where you configure how the application is executed inside the container.

 

Step 5: Build the Docker image

Now that we have defined the Dockerfile, let’s build a docker image for our application. Type the following command from the root directory of the project to build the docker image .

   docker build -t spring-boot-mysql .     

spring-boot-mysql is name of the docker image and . is to define path which contains Dockerfile to be referred to build image from.

 

Step 4: Link and Run the docker image

Once you have a docker image, you can run it using docker run command like so –

          docker run --name spring-boot-mysql -d --link mysql-dev-server:db -p 8081:8081 spring-boot-mysql        

Output:

In the run command, we have specified that the port 8081 on the container should be mapped to the port 8081 on the Host OS(Local Machine).

Once the application is started, you should be able to access it at http://192.168.99.100:8081/

192.168.99.100 – I have used Windows 10 docker toolbox for this demo . This is the default IP of the Docker machine which can be seen after docker toolbox is loaded as below –

-it option – interactive mode .

-p option- mapping containers port to host machine’s port .

mysql-dev-server – Its the MYSQL database container .

spring-boot-mysql – Its Spring boot application container.

–link – To link these two containers together

-d option –  To run the container in the background or Detached mode.

 

Step 5: Check the output of above Application in browser

http://192.168.99.100:8081/

 

Step 6: Push the docker image to docker hub

We can push our image to docker hub so that other people can use it . Below steps are required to push the image to docker hub –

  • Login with your docker ID –

[email protected]:~$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: anupbhagwat7
Password:
Login Succeeded

  • Tag the image –

docker tag image username/repository:tag

We will tag our current image –

docker tag spring-boot-mysql anupbhagwat7/spring-boot-mysql:0.0.1-SNAPSHOT

Replace my name(anupbhagwat7) with your respective docker ID. Once the image is tagged , you need to push it to docker hub.

  • Push the image to docker hub

docker push anupbhagwat7/spring-boot-mysql:0.0.1-SNAPSHOT

That’s it, You can now access this image on docker hub through below link –

https://hub.docker.com/r/anupbhagwat7/spring-boot-mysql/

 

Step 7: Pull the docker image from docker hub and run it

After we publish the image to docker hub, anyone can pull this image and run it in their environment. Type the following command to pull and run the image on your machine that we just pushed to docker hub –

docker run -it -p 8080:8080 anupbhagwat7/spring-boot-mysql:0.0.1-SNAPSHOT

The docker run command pulls the image from docker hub if it is not available locally, and then runs it.

OR

You can pull the image and run it with two different commands –

docker pull anupbhagwat7/spring-boot-mysql

docker run -it -p 8081:8081 anupbhagwat7/spring-boot-mysql:0.0.1-SNAPSHOT

You see how easy it is to share your image with others. People don’t need to install anything whatsoever to run your application. They just need to pull the image and run it with docker.

 

Using dockerfile-maven-plugin to Automate the Docker image creation and publishing

We can automate everything from building the docker image to publishing it on docker hub using dockerfile-maven-plugin.

Add below plugin code to you projects pom.xml file –

<!-- This plugin is used to create a docker image and publish the image to docker hub-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<!-- replace `anupbhagwat7` with your docker id-->
<repository>anupbhagwat7/spring-boot-websocket-chat-demo</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
<executions>
<execution>
<id>default</id>
<phase>install</phase>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
</plugin>

The plugin’s configuration includes the remote repository name and the repository tag. Please replace the username anupbhagwat7 with your docker Id in the <repository> element.

We’re also passing the JAR_FILE argument inside <buildArgs> element. Remember we had added ARG JAR_FILE instruction to the Dockerfile? The argument passed here will override that value.

Here is how you can build the docker image using docker-file-maven plugin –

mvn package dockerfile:build

This command will package the application into jar file and then creates docker image.

Finally, you can push the docker image to the docker registry using dockerfile:push command –

mvn dockerfile:push

Now to automate it further, we need register the dockerfile:build and dockerfile:push goals to the install phase of maven build life cycle using the <executions> tag.

So whenever you run mvn install, the build and push goals of dockerfile-maven-plugin are executed, and your docker image is built and pushed to docker hub.

The dockerfile-maven-plugin uses the authentication information stored in any configuration files ~/.dockercfg or ~/.docker/config.json to push the docker image to your docker profile. These configuration files are created when you login to docker via docker login.

You can also specify authentication details in maven settings.xml or pom.xml files.

Leave a Comment

Bitnami