Tomcat Docker Example

 

In that file define all 3 tomcat container entries and change the server.xml file and tomcat-users.xml and deploy our app to ROOT location in tomcat. Check my github repo Once we defined the yaml file then use single command like docker-compose up for start all 4 container up and running. We can also use docker-compose -d up for run in background. Objective Run Apache Tomcat in a Docker container and deploy a servlet. We are going to use one of the Tomcat images on Docker Hub. There are several images using different versions of the JRE. The JRE version should match the version we'll use to develop the servlet. Refer to the previous posts about Docker.

Example

In this article, you’ll learn how to build a docker image for running a spring boot application. I’ll first give you a brief idea of docker, then we’ll create a docker image for our spring boot application, and run it locally. Finally, we’ll push the docker image to docker hub.

So let’s get started!

A Quick introduction to Docker

Docker is a software platform that enables developers to develop, ship, and run applications anywhere with the help of containers.

Now what the heck is a container and what problem does docker solve with containers?

Well, Let’s understand that by asking a few questions. Does any of the following sound familiar to you?

  • “It runs on my machine!!”

  • “I think your Tomcat version is outdated!

  • “I don’t want to install 10 different libraries and tools before being able to run your application. Can’t it come in a packaged form with all the libraries and tools it needs?”

  • “We have applications written in different languages, tools, system libraries, and environments. Is there a way we can run them independently on the same infrastructure?”

I bet some of them does.

Docker solves these problems by creating a lightweight, standalone, executable package of your application that includes everything needed to run it including the code, the runtime, the libraries, tools, environments, and configurations.

These standalone executable packages are called docker images. And a running instance of a docker image is called a docker container.

Now, these container images can be shared, shipped and run anywhere in any environment. They will behave exactly the same regardless of the environment they run in.

Moreover, you can run multiple containers of completely different configurations on the same infrastructure. All containers are completely isolated and run independently from each other.

Cool, isn’t it? Well, let’s now learn how to run a spring boot application inside a docker container. But before that, go ahead and install docker community edition on your platform.

Also Read:What is a Container and What is the difference between Containers and Virtual Machines

Example

Spring Boot with Docker: Dockerizing a Spring Boot application

1. Downloading the application to Dockerize

Tomcat Docker Example

In this article, we’ll dockerize a web socket based group chat application built with spring boot. You can download the application from github -

There is a live demo of this application hosted on Heroku. Go check that out if you’re curious. You can also read the tutorial to learn how to build it from scratch.

All right! Let’s now learn how to create a docker image of this spring boot application.

2. Defining a docker image with Dockerfile

Go to the application’s root directory and create a new file named 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 -

The Dockerfile is very simple and declarative. Let’s go through each line of the Dockerfile and understand the details.

  • FROM: 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. It is a very lightweight OpenJDK 8 runtime image that uses Alpine Linux. (It’s perfect for small Java microservices.)

  • LABEL: 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.

    The VOLUME instruction creates a mount point on the container with the specified path. When you run the container, you can specify the directory on the Hot OS to which the given mount point will be mapped to. After that, anything that the container writes to the mounted path is written to the mapped directory on the Host OS.

    One of the most common use cases of volumes is to store the log files generated by the container on the Host OS. For example, Let’s say that your application writes log files to a location /var/log/app.log.

    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.

    You can learn more about Volumes from the official documentation.

  • EXPOSE: As the name suggests, this instruction allows you to expose a certain port to the outside world.

  • 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.

    Once defined, the variable can be used by the instructions following it.

  • 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.

3. Building the Docker image

Now that we have defined the Dockerfile, let’s build a docker image for our application.

Before building the docker image, you need to make sure that you’ve packaged the application in the form of a jar file using maven. You can type the following command from the root directory of the project to package it -

The above command creates a jar file in the target directory of the project.

Let’s now build the docker image by typing the following command -

That’s it. You can now see the list of all the docker images on your system using the following command -

This should display our newly built docker image.

4. Running the docker image

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

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

Once the application is started, you should be able to access it at http://localhost:5000.

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 -

The above command starts the container in the background and gives you the container ID. You can see the list of all containers running in your system using the following command -

5. Pushing the docker image to docker hub

Now let’s push the docker image to docker hub so that other people can download and consume our image.

  • Login with your Docker Id

  • Tag the image

    To push a local image to docker registry, you need to associate the local image with a repository on the docker registry. The notation for the repository on docker registry is username/repository:tag.

    To tag an image, we use the docker tag command -

    For example, Here is how we can tag the local image of our spring boot application -

    Make sure to replace my username callicoder with your docker id in the above command.

    Once the tagging is done, you can type docker image ls in the terminal to see the newly tagged image -

  • Push the image to docker hub

    Finally, use the docker push command to push the tagged image to docker hub like so -

    Again, don’t forget to replace the username callicoder with your docker id.

    And That’s all! The image is now published on the docker hub at the following link -https://hub.docker.com/r/callicoder/spring-boot-websocket-chat-demo/

6. Pulling the image from docker hub and running 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 -

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

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.

Automating the Docker image creation and publishing using dockerfile-maven-plugin

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

Add the plugin to the pom.xml file with the following configurations -

The plugin’s configuration includes the remote repository name and the repository tag. Please replace the username callicoder 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 -

Tomcat Docker Example Excel

The above command first packages the application in the form of a jar file, and then builds the docker image.

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

Now to automate it further, we have registered 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. Check out the official Readme of the plugin for more information on that.

Conclusion

The application that we dockerized in this article is very simple. It doesn’t use any database or communicate with other services. In the next article, you’ll learn how to dockerize a complex service with a database using docker compose.

As always, Thanks for reading. Have a good day.

This tutorial demonstrate how to deploy a war file into docker image.

I’ll be using 2 approach:

  1. Embedded war file to build into docker image.
  2. Externalize war file by mounting with docker tomcat path.

Structure

Approach 1

Let’s get started.

Step 1) Prepare a Dockerfile
Step 2) Run build custom image base on docker hub tomcat image
Step 3) Start docker containers

Dockerfile

  1. Prepare a Dockerfile with the following content.
  2. Copy the war file from out from the target folder.

Build docker image

Now run the follow command to docker image name webserver with your Dockerfile in current directory. First time to build docker image will require download and may take longer times.

Run docker container

Run docker container with interactive mode.

Test your container

Open a browser with URL http://192.168.59.103:8080/dockerwar/

Approach 2

Approach 2 are slightly different, let’s modified the Dockerfile, we just extends the tomcat based image.

Dockerfile

Build docker file

Eclipse classpath

In this example, I’m using eclipse classpath “target” folder to mount with docker container’s /webapps/ directory.

Delete all files in “target folder”

Docker Pull Tomcat

Before you start the container run “mvn clean package” to your project.

Run docker

Run the following command in interactive mode, mount your eclipse build path to your docker container tomcat webapps folder.

Tomcat Dockerfile Example

Test your container

Open a browser with URL http://192.168.59.103:8080/dockerwar/

Tails container logs

You can either start your container without interactive mode -it or run another terminal to interact with your container. Eg, my container instance is e6b2.

Tomcat Docker Example Pdf

To list all the log files:

Docker Tomcat Jmx

To tail the log file: