Dockerizing Spring boot Rest Webservice Application

Dockerizing a Spring boot Rest Webservice Application

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

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/SpringBootRestful.git

This is a simple spring boot Restful Webservice application project.

Step 2: Maven clean and package the application 

 cd SpringBootRestful/

mvn clean package 

Step 3:  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 8080 available to the world outside this container
EXPOSE 8080

# The application's jar file
ARG JAR_FILE=target/SpringBootRestful-0.0.1-SNAPSHOT.jar

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

# Run the jar file
ENTRYPOINT ["java","-jar","/SpringBootRestful.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 3: 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-rest .

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

Output:

Step 4: Run the docker image

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

docker run -it -p 8080:8080 spring-rest

Output:

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

Once the application is started, you should be able to access it at http://EC2_INSTANCE_IP:8080/tasks

-it option – interactive mode .

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

spring-rest – Its Spring boot application container.

The container runs in the foreground, and pressing CTRL + C will stop it. Let’s now see how to run the container in the background.

Running the docker image in the background, in detached mode.
You can use the -d option in docker run command to run the container in the background –

docker run -d -it -p 8080:8080 spring-rest

 

Step 5: Check response in POSTMAN tool

Below is the response from webservice –

 

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-rest anupbhagwat7/spring-rest: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-rest: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-rest/

 

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-rest: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-rest

docker run -it -p 8080:8080 anupbhagwat7/spring-rest: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