TechnologyAug 11, 2015

Docker for the Enterprise, Part 2: Containerizing an Application

Simon Saugier, and Credera Team

This is the second in a multi-part, multi-track blog series on Docker for the Enterprise. In case you missed it, here is Part 1.


I’ll admit when I first was learning about Containerization, I was overwhelmed. It seemed that there were many ways to accomplish similar goals, and it was hard to grasp how it all fit together.

In this part of the blog series, we will walk through the containerization process by building a Docker image for our sample application.

  • First, we’ll give an overview of our sample application that we want to containerize. It’s a simple Spring Boot app that downsamples images.

  • Next, we’ll show how to build this app into a Docker image.

  • After that, we’ll show how to upload the image we’ve created to the Docker Hub.

  • Finally, we’ll show how to run our image as a container on any machine that has Docker installed.

sample application

We created a sample application that we could use to illustrate how to use Docker. For our application, we wanted to create something simple but imaginably useful. Something that could also stress a host’s processing, bandwidth, and storage resources. For this, we developed an image downsampling application. It takes in a URL of an image and returns URLs of that same image in a thumbnail size appropriate for blog posts and mobile use

Docker 1

Sample Application Process Flow

Although we could have chosen any language and framework, we chose Java and Spring Boot for their flexibility and ease of development. For this post, we will have a single application within a single container. We chose this approach over a distributed architecture for simplicity. In future posts, we may reconsider this decision for scalability.

building a docker image

Now let’s get our application loaded into a Docker image by using a Dockerfile. Our Dockerfile is listed below:

# Specifies the starting image from which this docker image will be # built. We want this to be as small as possible while still # providing the required dependencies.FROM jlrigau/maven-git # The sources are added directly into the image from the git working tree ADD app /root/app   # Setting the workdir allows us to run mvn package from the proper # directory WORKDIR /root/app   RUN mvn package   RUN mkdir -p /var/opt/downsample/download   RUN mkdir -p /var/opt/downsample/static   # CMD is not run as part of the image, but rather is the default # command that will be executed when a container is executed. CMD java -jar /root/app/target/simple-app.jar

To build our image using this Dockerfile, we can use the following command:

$ docker build -t downsampler . … Successfully built 75b90442294b

What is an image? An image is a snapshot of the file system after we execute the commands in the dockerfile.

deploying an image

Now that we’ve loaded our sample application into a Docker image, let’s upload it to the Docker Hub. This will require an account. Once you have created an account, you will need to re-tag your image to match your repository ID. For our sample application, we’ve created “zanegrey/downsampler”. You will replace “zanegrey” with your Docker account name.

$ docker tag downsampler /downsampler

You can now push the image.

$ docker push /downsampler

Once the image is pushed, you can log onto another machine running the Docker daemon and run the same Docker image.

$ docker run -d -p 80:8080 /downsampler

You can also use the image we built, located at zanegrey/downsampler:blog1-initial

What just happened behind the scenes? Docker downloaded the image we uploaded to the Docker Hub in the previous step and started it as a container on this machine.

We can verify our application is running and check its logs.

$ docker ps CONTAINER ID         IMAGE               COMMAND               CREATED             STATUS             PORTS                 NAMES 8a39fe873187         659d00211c11         "/bin/sh -c 'java -j   5 minutes ago       Up 5 minutes>8080/tcp   nostalgic_mayer $ docker logs 8a39fe873187...

Notice that Docker is now referring to our image as a container. If you need, refer to Docker’s explanation here on the difference between an image and a container.

Now that we have the image deployed, let’s try out the application!

$ curl 'http://localhost/downsample' -H 'Content-Type: application/json' --data-binary ' {"url":""}' ... {"msg":"Here are your images", "urls":{"thumbnail":"http://localhost/ds/293F02191DA8D6D5329821BA2F5453D1.png","blog":"http://localhost/ds/A443AE9F4292E3932FB2FD9027ABA9AC.png","mobile":"http://localhost/ds/E6EBC85E16733005F85C52C9FA017C82.png"}}

Note: If you are using boot2docker or are running the Docker daemon somewhere besides your localhost, put in the Docker daemon’s IP address in the curl command instead of “localhost”.

Notice that you can copy any of these URLs and paste them into your browser to view the resized image.

To shutdown containers, use `docker stop`.

$ docker stop <container id>

to review…

Let’s take a look at the changes we’ve made:

Before Docker, our application ran on a Linux machine and presumed that all of the files it needed (e.g., Java, simple-app.jar, etc.) were present and available. With Docker, all of the files required are now included together in an image and run in a container

Docker 2

Before Docker, our build process deployed the required jar by copying it to the target machine. With Docker, our image is built and uploaded to the Docker Hub and then downloaded automatically using ‘docker run’.

Docker 3

where to go from here?

We did it! We got our application to run in a Docker container! However, are we realizing the full potential of Docker? Specifically:

  • Is our application more scalable?

  • Is our application more secure or isolated?

  • Have we increased the portability of our application?

To realize these benefits, we will need to start thinking of our application differently. We need to start thinking in containers.

Plus, with the addition of a new layer of abstraction comes new complexities. Here are some questions to get you started:

  • What happens to the data in a container when the machine has a power failure?

  • How does Docker affect security compliances?

  • What happens if an application becomes overburdened?

  • How does our DevOps workflow change with Docker?

We will address these questions and others in following posts in this series. Stay tuned!