Deploy an Maven application on Apache Tomcat using Jenkins CICD

Rajendra ThapaRajendra Thapa
8 min read

Create an EC2 instance and start installing JAVA, MAVEN and TOMCAT

Create another EC2 instance to install Jenkins

Install java 17

sudo apt update
sudo apt install openjdk-17-jdk -y
sudo apt install openjdk-17-jre -y
java --version

Install the latest Maven version

First, we’re going to find the most recent release – it’s available on the Downloading Apache Maven page:

wget https://dlcdn.apache.org/maven/maven-3/3.9.4/binaries/apache-maven-3.9.4-bin.tar.gz
sudo tar xf apache-maven-3.9.4-bin.tar.gz -C /opt
ls -la /opt

x – extract the given file from an archive (operation mode);

f – use archive file (device selection);

C /opt – change to the /opt directory before performing any operations (local file selection).

Set environment variables for Maven

Now we will permanently set the environment variables for Maven. First, I’m going to create a symbolic link between the apache-maven-3.9.4 and new /opt/maven locations so that I don’t have to edit the variables the next time I update Maven:

sudo ln -s /opt/apache-maven-3.9.4 /opt/maven
cd /opt

I’m going to use the link as a value of the Maven environment variables. This way, the next time I update Maven I will simply change the symbolic link to point to a newer release.

I’m going to create a new script file called maven_home.sh and put it in the /etc/profile.d/ directory:

sudo nano /etc/profile.d/maven_home.sh

Copy the following lines and paste it (Shift+Insert) into the file:

export M2_HOME=/opt/maven
export MAVEN_HOME=/opt/maven
export PATH=${M2_HOME}/bin:${PATH}

Next, save and exit the file. Log out and log in back to the system. Verify with the echo command that the M2_HOME and MAVEN_HOME values are correct, and the PATH variable contains an entry for maven. Finally, you can check the version information for Java and Maven with the following command:

sudo reboot
mvn --version

Install Git

sudo apt update
sudo apt install git -y
git --version

Install TOMCAT

Running Tomcat under the root user is a security risk. We’ll create a new system user and group with a home directory /opt/tomcat that will run the Tomcat service. To do so, enter the following command:

sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat
# Update the packages
sudo apt update

# Download tomcat
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.78/bin/apache-tomcat-9.0.78.tar.gz -P /tmp

# Extract Tomcat
sudo tar -xf /tmp/apache-tomcat-9.0.78.tar.gz -C /opt/tomcat/

Tomcat is updated regularly with security patches and new features. To have more control over versions and updates, we’ll create a symbolic link called latest, that points to the Tomcat installation directory:

sudo ln -s /opt/tomcat/apache-tomcat-${VERSION} /opt/tomcat/latest
sudo ln -s /opt/tomcat/apache-tomcat-9.0.78 /opt/tomcat/latest

The system user that was previously created must have access to the Tomcat installation directory. Change the directory ownership to user and group tomcat:

sudo chown -R tomcat: /opt/tomcat

The shell scripts inside the Tomcat’s bin directory must be executable

sudo sh -c 'chmod +x /opt/tomcat/latest/bin/*.sh'

Instead of using the shell scripts to start and stop the Tomcat server, we’ll set it to run as a service called tomcat.service

sudo nano /etc/systemd/system/tomcat.service

Paste the below

[Unit]
Description=Tomcat 9 servlet container
After=network.target

[Service]
Type=forking

User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom -Djava.awt.headless=true"

Environment="CATALINA_BASE=/opt/tomcat/latest"
Environment="CATALINA_HOME=/opt/tomcat/latest"
Environment="CATALINA_PID=/opt/tomcat/latest/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/latest/bin/startup.sh
ExecStop=/opt/tomcat/latest/bin/shutdown.sh

[Install]
WantedBy=multi-user.target

Modify the JAVA_HOME variable if the path to your Java installation is different.

Save and close the file and notify the system that a new unit file exists:

sudo systemctl daemon-reload

Enable and start the Tomcat service:

sudo systemctl enable --now tomcat

Check the service status:

sudo systemctl status tomcat

The output should show that the Tomcat server is enabled and running:

You can start, stop and restart Tomcat the same as any other system service:

sudo systemctl start tomcat
sudo systemctl stop tomcat
sudo systemctl restart tomcat

Tomcat runs on port 8080 likewise Jenkins, so we will change Tomcat port to 8000. We will configure it server.xml

sudo nano /opt/tomcat/latest/conf/server.xml

Save the changes. Stop and restart the tomcat again

sudo systemctl start tomcat
sudo systemctl status tomcat

Access the Tomcat server using <Instancepublicip:8000> in a web browser.

If you click on Manager App, it will throw 403 Access Denied

To fix this access issue we need to configure the context.xml file and tomcat-users.xml

sudo nano /opt/tomcat/latest/webapps/manager/META-INF/context.xml

Comment out the Valve ClassName Section

Configure tomcat-user.xml

sudo nano /opt/tomcat/latest/conf/tomcat-users.xml

Add the below roles and password

 <role rolename="manager-gui" />
  <user username="admin" password="admin" roles="manager-gui" />
  <role rolename="admin-gui" />
  <role rolename="manager-script" />
  <user username="admin" password="admin" roles="manager-gui,admin-gui,manager-script" />

Stop the Tomcat server and start it

sudo systemctl start tomcat
sudo systecmctl status tomcat

Access the Tomcat server

Click on Manager App and provide the user and password details

In case any error occurs like (/manager/html) is not available".

sudo chmod -R 777 /opt/tomcat

Now our Tomcat server is ready.

Install Jenkins

Create a new EC2 instance and install Jenkins

Java installation commands

sudo apt update
sudo apt install openjdk-17-jre -y
java -version

Jenkins installation commands

curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y

Start Jenkins

You can enable the Jenkins service to start at boot with the command:

# Enable the Jenkins service to start at boot
$ sudo systemctl enable jenkins

# start the Jenkins service
$ sudo systemctl start jenkins

# check the status of the Jenkins service
$ sudo systemctl status jenkins

Access the Jenkin server with <EC2PublicIP:8080> in a web browser

# Copy the adminpassword from the terminal and click on continue
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Click on Install suggested Jenkins

Starts installing all the required plugins

Configure your Username, Password, Fullname, Email and click on save and continue

Click on Save and Finish

Click on Start using Jenkins

Let's integrate GitHub with Jenkins through SSH

Create an SSH key on the EC2 instance on which Jenkins is installed

C0mmand to generate SSH key
ssh-keygen

Once you paste the command, provide the path where you want to store the keys, else you can just hit enter and continue.

By default, both id_rsa(private) and id_rsa.pub(public key) keys are stored in.ssh directory

cd .ssh
cat id_rsa.pub

Copy the id_rsa.pub from the terminal and open your GitHub account and navigate to Settings> SSH and GPG Keys > New SSH key

Provide the name and paste the id_rsa.pub in the key section and click on Add SSH key

Our key is added in GitHub now we need to configure the same in the Jenkins server

Navigate to Jenkins Dashboard > Manage Jenkins > Security - Credentials > Global > Add Credentials

Select the Kind as SSH Username with the private key

username = Ubuntu

Description as Gitcreds

Private key > Enter directly > Add > Paste the Private key(id_rsa) and click on Create

Our credentials are created and the integration between Jenkins and GitHub is done

Install all the Plugs required for deploying .war file in TOMCAT server using Jenkins

Jenkins Dashboard > Manage Jenkins > Plugins > Available Plugins and install Deploy to container Plugin

Jenkins Dashboard > Manage Jenkins >System Configuration > Tools and add the following

and save it.

Create a freestyle project in Jenkins

Jenkins dashboard > click on + New item

Provide the name and select the project as a Freestyle project

In the general section add a description and select it as a GitHub project with a URL

https://github.com/rjthapaa/maven-tomcat

Under Source Code Management, select it as Git and add the Git repository URL

For credentials use the ubuntu (git creds) that we previously created

Select the branch as main, where we have our code

Under Build steps, select it as Invoke top-level Maven targets.

Select the Maven Version and Goals as a clean package

Under Post-build Actions, select it as Deploy war/ear to a container

WAR/EAR files as **/*.war

Context path can be anything and Containers should be your Tomcat version 9.x

Add the credentials of the tomcat in Manage Jenkins > Credentials > System > Global credentials (unrestricted) as we did for Git credentials

Add the Tomcat instance ip with a port no in the TOMCAT URL section and click on Save

Click on Build now to deploy the Web application

Deployment has started and is successful

Click on Success > Console Output > Console output

Web application deployment is successful, let's check our application in the TOMCAT server.

Click on Manager App

Under Applications and Path, you can see /rjthapaa the context path that we provided during configuring Post-build actions in Jenkins

Click on /rjthapaa to access the application

We can also auto-trigger the deployment by using GitHub hook trigger for GITScm polling

Open the project in Jenkins, under Build triggers, enable GitHub hook trigger for GITScm polling

Go to the GitHub repo and make some changes to the code and commit it.

Pollscm had auto-triggered the jobs in Jenkins

Check the application changes in the TOMCAT server

0
Subscribe to my newsletter

Read articles from Rajendra Thapa directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajendra Thapa
Rajendra Thapa

DevOps Engineer