Dockerize Spring boot application

Hi Folks,

In today’s post we’ll cover about the following things:

  • Create docker image of spring boot application
  • Run it as docker container

Create docker image from spring boot application

Firstly we’ll create a simple spring boot application which we have to dockerize. To create a simple spring boot application refer the link.

We’ll create a simple controller in this as below:

@RestController
class DockerController
{
    @GetMapping("testDocker")
    public Object testDocker()
    {
        return "Docker is running";
    }
}

In this controller, there is simple testDocker mapping which is returnning a simple string.

Following is the pom file for the same:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>threadminions</groupId>
    <artifactId>create-docker</artifactId>
    <version>1.0</version>
    <name>create-docker</name>
    <description>Demo project for Spring Boot to create docker image</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

As spring boot project has been setup now it’s time to create a docker image from it.

To create a docker image we need to create a file called Dockerfile which is docker own build format for an image.

DockerFile is a kind of script which contains commands which are used to create an image file. To know more about docker file follow the link.

Now we’ll create our first dockerfile as below:

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

# Add Maintainer Info
LABEL maintainer="asxxxxx@gmail.com"

# Add a volume pointing to /tmp
VOLUME /home/decimal/tmp

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

# The application's jar file
ARG JAR_FILE=target/create-docker-1.0.jar

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

# Run the jar file 
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker.jar"]

It contains following basic commands:

FROM – The keyword FROM, tells Docker to use a given image with its tag as build-base. If this image is not in the local library, an online-search on DockerHub, or on any other configured remote-registry, is performed.

In this example we are using Java 8 as a base image because to run our spring boot application we need java 8.

LABEL maintainer – A LABEL MAINTAINER is usually an email address, identifying the author of an image

VOLUME – Dockerfile’s VOLUME specify one or more volumes given container-side paths

EXPOSE – The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. In our case it is 9001. EXPOSE doens’t make the ports accessible to the host.

ARG – The ARG instruction defines a variable with a default value. You can override the default value of the variable by passing it at build time.

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

ENTRYPOINT – This will be the executable to start when the container is booting. We must define them as JSON-Array, because we will use an ENTRYPOINT in combination with a CMD for some application arguments.

As our dockerfile is ready so it’s time to build an image from the application. Make sure that your dockerfile should be in the root directory of your project.

Before creating an image, let’s build the project will mvn command as below:

mvn clean install

It will create a build of the project inside target folder at the root path of your project.

After that run following command at the root path in order to create an image

docker build -t docker-demo .

docker build command is use to build the image which read instructions from the dockerfile. Here -t option is use to tell the image name and docker-demo is the actual image name which will be created. To know more about docker build follow the link.

If command is successfully run then following output should be shown:

Sending build context to Docker daemon  16.89MB
Step 1/7 : FROM openjdk:8-jdk-alpine
 ---> 21a93502ddd8
Step 2/7 : LABEL maintainer="ashishbansal689@gmail.com"
 ---> Using cache
 ---> 193be7edd687
Step 3/7 : VOLUME /home/decimal/tmp
 ---> Using cache
 ---> 489603737ff6
Step 4/7 : EXPOSE 9001
 ---> Using cache
 ---> 45ba6d26c5c6
Step 5/7 : ARG JAR_FILE=target/create-docker-1.0.jar
 ---> Using cache
 ---> 946a2c4ffa3a
Step 6/7 : ADD ${JAR_FILE} docker.jar
 ---> Using cache
 ---> 6105495e7366
Step 7/7 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker.jar"]
 ---> Using cache
 ---> 14b169792d28
Successfully built 14b169792d28
Successfully tagged docker-demo:latest

As you can see docker image has been created successfully with name docker-demo with tage latest.

Now it’s time to run the image.

Run docker image as container

In order to run newly created image following is the command:

docker run --name docker-demo -p 9001:9001 docker-demo:latest

docker run command is use to run the image. Here

–name option is use to give the name to the container. It is optional if it is not given then it is automatically chosen by the docker.

-p option is use to mount the container port with the host port. It means when we will hit the 9001 port then it will be redirected to our application.

To know more about docker run follow the link.

When you run the aforemention command and if everything goes well then spring boot application should be started as below:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-24 06:43:17.913  INFO 1 --- [           main] t.createdocker.CreateDockerApplication   : Starting CreateDockerApplication v1.0 on 8ea05e6bf63e with PID 1 (/docker.jar started by root in /)
2019-02-24 06:43:17.929  INFO 1 --- [           main] t.createdocker.CreateDockerApplication   : No active profile set, falling back to default profiles: default
2019-02-24 06:43:21.067  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9001 (http)
2019-02-24 06:43:21.150  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-02-24 06:43:21.164  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.14]
2019-02-24 06:43:21.187  INFO 1 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2019-02-24 06:43:21.485  INFO 1 --- [           main] o.a.c.c.C.[.[localhost].[/docker]        : Initializing Spring embedded WebApplicationContext
2019-02-24 06:43:21.485  INFO 1 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3359 ms
2019-02-24 06:43:21.884  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-02-24 06:43:22.511  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9001 (http) with context path '/docker'
2019-02-24 06:43:22.520  INFO 1 --- [           main] t.createdocker.CreateDockerApplication   : Started CreateDockerApplication in 5.544 seconds (JVM running for 7.424)

As you can see our application has been started successfully.

Just hit the browser with the url http://localhost:9001/docker/testDocker and it should give following output:

Docker is running

Download the sample project from here.

In my next post I will cover how to create an image using dockerfile-maven plugin.

One thought on “Dockerize Spring boot application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s