Deploy a war app on Docker Container Using Jenkins

In this article, I will demonstrate how to deploy a war application on the Tomcat Docker container using the Jenkins build tool.

Pre-requisites

  1. Ubuntu machine installed with Docker service ( you can use Redhat or Centos machine)
  2. A server installed with Jenkins build tool.
  3. Sample code in the GitHub repository.

Docker Installation

Execute the below commands to install the Docker service (version 19.03.6 ) on Ubuntu (18.04) machine.

sudo apt-get update
sudo apt-get install docker.io 
sudo systemctl start docker 
sudo systemctl enable docker 
docker --version

 

Once the Docker installation is completed, follow the below steps.

Jenkins Installation

For Jenkins installation refer to the below link.

Jenkins installation

Sample Code on Github repository

I already have a sample Java application is in Github repository, you can use the same or you can develop a new application.  To clone my repository use the below link.

https://github.com/techiescorner/Hello-World-Code.git

Application Deployment

To deploy the application we need a Tomcat container as our application is a war file (written in Java).  To create a Tomcat container first we need a Tomcat container image, from this image we can create a container. Execute below command to pull the latest Tomcat image from the Docker Hub repository.

sudo docker pull tomcat
sudo docker images

REPOSITORY   TAG      IMAGE ID            CREATED             SIZE
tomcat       latest   31a47677561a        2 hours ago         529MB

Execute the below command to create a Tomcat container from this image.

sudo docker run --name tomcat-container -p 8080:8080 tomcat:latest
  • docker run:  to start a container
  • –name:  Name of the container
  • -p:   Internal and external port number for the Tomcat service
  • tomcat:latest :  Name of the image used to create the container.

To confirm the Tomcat container started, open the browser and try to access the service with the help of server public IP address and the port 8080. But I got an “HTTPS” status 404 – not found” error message when I tried.

To debug this issue, stop the container and run the container in the background. By pressing ctrl+C terminate the running container.

Remove the container and run it in the background. To start the Docker container in the background using “-d” argument.

 

Login to the container and check the Tomcat default directory. Execute below command to log in to the container.

sudo docker exec -it tomcat-container bash
root@4c1db6d6d72a:/usr/local/tomcat# ls
root@4c1db6d6d72a:/usr/local/tomcat# cd webap
root@4c1db6d6d72a:/usr/local/tomcat/webapps# ls

“/usr/local/tomcat/weapps” is the directory where Tomcat default files will load when we access, but, there is no file present in this directory. This is the reason for the 404 files not found error.

Integrate Docker with Jenkins

We have created a Tomcat docker container next, we have to integrate it with Jenkins server.

The integration is with the help of “publish over ssh plugin, so to install this plugin,  Log in to the Jenkins server and click Manage Jenkins -> Manage plugins -> Available.

Search publish over ssh in the search bar and select the plugin from the search result.

 

Click “Install without restart button” to complete the installation.

To connect with our Docker server we need user credentials. For this create a new user in the docker server.

sudo adduser dockeruser

Add this user to the docker user group. Get docker service username from the /etc/group file and execute the below command to add the “dockeruser” to the docker service group.

sudo usermod -aG docker dockeruser

 

User is ready, next add this user credential in Jenkins. For this login to Jenkins server and click on Manage Jenkins -> Manage System -> Add ssh server ( Under publish over ssh)

 

Click on the advance button and tick use password authentication, add password in the given box. Click the “Test configuration” button to confirm the user details is valid. But I got the following error on my validation.

jenkins.plugins.publish_over.BapPublisherException: Failed to connect and initialize SSH connection. Message: [Failed to connect session for config [Docker-server]. Message [Auth fail]]

This is because we haven’t enabled ssh login on the Docker server. Go back to Docker server and edit /etc/ssh/sshd_conf and set

“PasswordAuthentication yes”

Restart the sshd service for the new changes

sudo systemctl restart sshd

I tested again from Jenkins and got a success message. Click Apply and Save button to complete the action.

Create a new Jenkins job to deploy on Docker

From the Jenkins, dashboard creates a new  Maven project and give a name to it.

Add git URL details under Source code management.

 

Select post-build action as “send files or execute commands over SSH”. Here the artifacts can send over the ssh to the Docker server.

 

Add source file location (Default location where Jenkin keeps the file in the Jenkins server) as webapps/target/*.war and add “Remove Prefix” as “webapps/target” ( Destination server it will not create the directory path)

Apply and save. We are ready to build our application. Click “Build now” to build the application.

Check the console output for any error. There is no error for me so I got the success message.

SSH: Connecting with configuration [Docker-server] ...
SSH: Disconnecting configuration [Docker-server] ...
SSH: Transferred 1 file(s)
Finished: SUCCESS

Log in to the Docker host and confirm the “webapp.war” file copied to the user home directory.

dockeruser@docker-node:~$ ls
webapp.war

We have successfully built an application from the Jenkins server and moved to the Docker server.

Next, we will create a container to host this application.

This time we can use a Dockerfile  (an automated way to create an image ) to create an image (Dockerfile is to create and NOT to create container). To know more about the Docker file I recommend you to read the below article

Dockerfile to create images

Create a Dockerfile (D must be capital) and add the following content.

FROM tomcat:latest
MAINTAINER Techiescorner
COPY ./webapp.war /usr/local/tomcat/webapps
  • FROM: Which parent image we have to create the new image
  • MAINTAINER: who is creating the image.
  • COPY: copy the file webapp.war in to “/usr/loca/tomcat/webapps” location in the image.

 

save the file and execute the below command to create the image.

docker build -t new-tomcat .

-t: Give a name to the new image.

From the above screen-shot, we can see the newly created images.

To host our war application create a container from the new image. Execute the below commands to list any running container and remove and start a new container.

docker ps -a 
docker stop tomcat-container 
docker rm tomcat-container
docker run -d --name tomcat-app -p 8080:8080 new-tomcat

Created the new container named tomcat-app. Access the public IP address of the docker host on the browser to confirm the application is loading.

Confirmed our application successfully loading. Next, we will make a few modifications to Jenkins Job then the deployment will happen automatically.

Automatic deployment of the artifacts

Before making the changes on the Jenkins job we will clean the existing images and container from the docker host.

$docker stop tomcat-app
tomcat-app

$docker images

REPOSITORY   TAG      IMAGE ID        CREATED             SIZE
new-tomcat   latest  8a97e50a44d2     18 minutes ago      529MB
tomcat       latest  31a47677561a     2 days ago          529MB

$docker rmi new-tomcat
Untagged: new-tomcat:latest
Deleted: sha256:7e38c31c1a618446e207da31e30df806de85e86067fae16e8b851f8

Removed all containers and   “new-tomcat” image.

Next, log in to the Jenkins and edit the existing job (Docker_deployment job).

Click configure to make the changes.  Add the following command in the “Exec command” section under the “Post Steps”

cd /home/dockeruser;
docker build -t new-tomcat .;
docker run -d --name dev-container -p 8080:8080  new-tomcat;

These commands execution will be taken care of by Jenkins.

Click Apply and Save. Click build now to trigger the build.

Click Console output from the “Build History” tab present in the left side panel to see the output.

SSH: Connecting with configuration [Docker-server] ...
SSH: EXEC: STDOUT/STDERR from command [cd /home/dockeruser; docker build -t new-tomcat .;
docker run -d --name dev-container -p 8080:8080  new-tomcat;] ...
Sending build context to Docker daemon  18.43kB

Step 1/3 : FROM tomcat:latest
 ---> 31a47677561a
Step 2/3 : MAINTAINER Techiescorner
 ---> Running in 542bce1a1af3
Removing intermediate container 542bce1a1af3
 ---> 967733f96533
Step 3/3 : COPY ./webapp.war /usr/local/tomcat/webapps
 ---> 56f26ff13df8
Successfully built 56f26ff13df8
Successfully tagged new-tomcat:latest
6e8e51b12b78e335138553466d59c59aba35dde9d35c735c63a17334e33fecf6
SSH: EXEC: completed after 3,804 ms
SSH: Disconnecting configuration [Docker-server] ...
SSH: Transferred 1 file(s)
Finished: SUCCESS

The build is a success, now login to docker host and check for any container is running.

Yes, 34 seconds ago the container is created successfully. Now, access the public IP address and port in browser to confirm it is working.

The deployment is successful.

 

Leave a Reply

Your email address will not be published. Required fields are marked *