# Step-by-Step Java CI/CD Pipeline Setup Using Jenkins, Maven, and Docker

**<mark>Prerequisites :</mark>**

1. Choose a Linux distribution (e.g., Ubuntu 22.04 LTS) for your EC2 instances.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723584562604/0f4d83ff-2b92-4bc5-8291-d6494bc6daa4.png align="center")

2. Need two EC2 instances (one for Jenkins and Maven, and the other for Docker).
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723403062445/403dc172-3947-4fc8-914d-15664a2ed154.png align="center")

3. Security Group Configuration : SSH: Port 22, Jenkins: Port 8080
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723584312688/a0ebaf10-cec3-4251-afe6-50f2728e39f7.png align="center")

4. SSH Key Pair
    
5. GitHub Repository
    

**<mark>Agenda :</mark>**

1 : Install Jenkins

2 : Install plugins

3 : Download and Install Maven

4 : Generate SSH key pairs in the Jenkins machine

5 : Configure the authorised key in the slave machine

6 : Configure node in Jenkins

7 : Install Docker

8 : Configure tools in Jenkins

9 : Create Jenkins file and Docker file in the Github repository

10 : Create a CI/CD pipeline

11 : Check the Docker Container Status

12 : Check & Access the Application URL

**<mark>Step 1 : Install Jenkins</mark>**

Update the System package

```plaintext
sudo apt update
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440603443/8157db59-b786-414a-a78f-78beb7be40d1.png align="center")

Install OpenJDK 17

```plaintext
sudo apt install openjdk-17-jre
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440630991/9115c4ac-9ad8-4ca8-93c3-eb9fc4684aa9.png align="center")

Verify the installation by checking the Java version

```plaintext
java -version
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440568464/dbbdaf0d-1bd0-431a-86ed-f0f4df15dc5f.png align="center")

Add Jenkins Repository

```plaintext
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
  https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440674130/b5df13d0-70f4-419c-a5da-81aa0931e651.png align="center")

Update the package list again

```plaintext
sudo apt-get update
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440714464/8b16d762-3a31-4672-9ab7-c5ee7349538a.png align="center")

Install the Jenkins

```plaintext
sudo apt-get install jenkins
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440783108/51969fb0-3ef2-4064-a9ff-bd6923f43209.png align="center")

Check the Jenkins status

```plaintext
sudo systemctl status jenkins
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723440834412/b76f6314-35d9-47c4-9e24-23a45e9b1ea8.png align="center")

Access Jenkins Web Interface

```plaintext
http://<ip address>:8080
```

Open the terminal and running the following command, will get get the jenkins password

```plaintext
cat /var/lib/jenkins/secrets/initialAdminPassword
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723441133804/b97393ff-d031-4fc8-b9e8-e60afa8afe15.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723403731317/e1a0acf3-0134-434d-a429-0087c73c9f36.png align="center")

**Install suggested plugins** or **Select plugins to install**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723403768157/e114676c-6263-42ca-b32f-b2e892bf3ce4.png align="center")

Create admin user name & password

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722068494692/7f12b877-9320-44e3-ac53-680e05b80344.png?auto=compress,format&format=webp align="left")

Now, Successfully installed Jenkins

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723403964285/4abac057-d841-40ca-ab16-3f720e9f7879.png align="center")

**<mark>Step 2 : Install plugins</mark>**

Click on `Manage Jenkins` &gt; Click on `Plugins` &gt; Click on `Available plugins`

In the search bar, type `maven` &gt;Select `Maven Integration` plugin &gt; Click on `Install`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723580025604/2ab2aa8d-59a1-4069-903f-2fc802ad57f1.png align="center")

In the search bar, type `Docker` &gt;Select `Docker` plugin &gt; Click on `Install`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723454121048/41a1b20b-6a14-4b51-b032-9859fa642f1f.png align="center")

In the search bar, type `Docker Pipeline` &gt;Select `Docker Pipeline` plugin &gt; Click on `Install`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723452038079/5c84c6c5-3957-413f-94f2-a6a526d83b6a.png align="center")

In the search bar, type `SSH` &gt;Select `SSH Agent` plugin &gt; Click on `Install`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723462172216/965f0d8e-a841-4b85-a87f-0549deda2ae7.png align="center")

**<mark>Step 3 : Download and Install Maven</mark>**

Update the system package

```plaintext
sudo apt-get update
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723444992230/8a0150c5-2da2-4bbe-87e8-13c3d3a674cc.png align="center")

Download the Maven installation file to the `/tmp` directory using the `wget`

```plaintext
wget https://dlcdn.apache.org/maven/maven-3/3.9.8/binaries/apache-maven-3.9.8-bin.tar.gz -P /tmp
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723449990287/abef103b-8599-4ab7-8ca9-fefb59317622.png align="center")

Once the download is complete, extract the installation file to the /opt directory:

```plaintext
sudo tar xf /tmp/apache-maven-3.9.8-bin.tar.gz -C /opt
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450025706/77c4c589-0e6a-45ec-90d7-f59eb572fd4f.png align="center")

Create a symbolic link leading to the Maven installation directory:

```plaintext
sudo ln -s /opt/apache-maven-3.9.8 /opt/maven
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450057989/4893bba7-eea3-40b2-97b9-6fcd593675a9.png align="center")

`Set Up Environment Variables`

Create and open the `maven.sh` script file in the `/etc/profile.d/` directory:

```plaintext
sudo nano /etc/profile.d/maven.sh
```

Add the following lines to the `maven.sh` file:

```plaintext
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export M2_HOME=/opt/maven
export MAVEN_HOME=/opt/maven
export PATH=${M2_HOME}/bin:${JAVA_HOME}/bin:${PATH}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450506052/2b9fb974-c8a4-41bd-a1c0-d1872e9a6e67.png align="center")

Use the `chmod` command to make the `maven.sh` file executable:

```plaintext
sudo chmod +x /etc/profile.d/maven.sh
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450130309/2b6af5b0-c5c7-49ad-99e7-26ca7976f6a1.png align="center")

Execute the `maven.sh` script file with the source command to set up the new environment variables:

```plaintext
source /etc/profile.d/maven.sh
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450153292/979dff1a-4e73-4cc5-b64c-bfd0dc9dced9.png align="center")

`Verify Maven Installation`

```plaintext
mvn -version
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723450755275/7fe837c2-1033-407b-a599-a59059b04424.png align="center")

**<mark>Step 4 : Generate SSH key pairs in the Jenkins machine</mark>**

Generate SSH key pairs on Jenkins machine

```plaintext
ssh-keygen -t rsa
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442382614/870bd5c6-69e1-43c1-b7d2-6f1bd4b01f42.png align="center")

Go to SSH path & Check Keypair

```plaintext
cd .ssh/
ls -lrt
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442415883/f80544e3-df6f-4003-a307-e4c2e274e291.png align="center")

**<mark>Step 5 : Configure the authorised key in the slave machine</mark>**

Go to Docker machine

Install OpenJDK 17

```plaintext
sudo apt install openjdk-17-jre
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723441833111/be05d9ff-47fb-45db-b31d-e07384502e72.png align="center")

Check & Verify the java

```plaintext
java -version
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442051539/4171c9c5-0ad9-4d72-a830-f1abf5253070.png align="center")

Go to Master machine, Copy the public key `id_`[`rsa.pub`](http://rsa.pub)

```plaintext
cat id_rsa.pub
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442531168/f56716f6-d7b7-48fd-902e-589d3ee05f8e.png align="center")

Paste that public key in the slave machine authorized keys

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442502928/a2018296-5ea2-49cb-b329-33ee48e1346f.png align="center")

**<mark>Step 6 : Configure node in Jenkins</mark>**

Go to `Manage Jenkins` &gt; Click on `Nodes`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723409340447/5bc925e8-4f95-44b9-babf-64cf7308f786.png align="center")

Click on `New Node`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723409402787/45b15499-c53f-4da2-a8ab-ac885196ad85.png align="center")

Node Name: `Slave 1` &gt; Select `Permanent Agent` &gt; Click on `Create`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723443955010/ba49e568-f09b-4362-b0d6-63056f8731b5.png align="center")

Number of executors : 2

Remote root directory : The directory where Jenkins will run jobs on the agent (e.g., `/home/ubuntu/jen` )

**Labels** : Tags that can be used to assign jobs to this node. `java`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723409572186/57ac974d-ef7e-4586-90ef-1efe28b4d4d5.png align="center")

Launch Method : Select `Launch agents via SSH`

Host : Enter the IP address of the agent `13.201.85.186`

Credentials : Add `Jenkins` .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442728623/c52c7b93-c68c-4014-981d-aae90fa0518d.png align="center")

Kind : Select `SSH Username with private key`

ID : Enter any name `Slave1`, Note : This id need to use Jenkinsfile

Username : Enter the slave machine username `ubuntu`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723577452012/2795cc71-3718-4b24-9bdc-5ea007c6c7de.png align="center")

Private key : Copy the private key from master machine & paste it

Click on `Add`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723409823106/2d14489b-c9f8-49cd-80fb-0384cd1b009d.png align="center")

Now, Select credentials : `ubuntu`

Host Key Verification Strategy : Select the `Non verifying Verification Strategy`

Click on `Save`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723442839655/715657db-a365-450f-b3ed-988c529c616b.png align="center")

Now, Check the Nodes page : Slave machine successfully added

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723444830945/81ae74d7-cf10-4cfd-94fa-ed6df967cdec.png align="center")

**<mark>Step 7 : Install Docker</mark>**

Go to 2nd instance

Update the system package

```plaintext
sudo apt-get update
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723445330285/2a9b839e-20a9-4a6e-a2f1-e85ddf258996.png align="center")

Install the docker

```plaintext
sudo apt-get install docker.io -y
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723445376896/278dbbca-31e1-4339-b105-919465581e0c.png align="center")

Start and enable the docker

```plaintext
sudo systemctl start docker
sudo systemctl enable docker
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723445417190/9ed4f1d9-85a3-4f35-8aaa-0035bf84e567.png align="center")

Check the docker status

```plaintext
sudo systemctl status docker
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723445484218/ee2e2ef2-416b-46ba-8542-77332f4a3185.png align="center")

**<mark>Step 8 : Configure tools in Jenkins</mark>**

Go to `Manage Jenkins` &gt; Go to `Git installations`

Name : `Default`

Path to Git executable : Enter git path `/usr/bin/git` &gt; Scroll down

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723492167853/5456664c-1fdb-4a12-9204-4bf5407feed3.png align="center")

Go to `Maven installations`

Name : `maven` &gt; Click on `Install automatically` &gt; Scroll down

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723492203665/d442d87b-8879-452b-b5c8-5d34ab34a22c.png align="center")

Go to `Docker installations`

Name : `docker` &gt; Click on `Install automatically` &gt; Click on `Save`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723492243768/9886f01a-0151-463d-93d1-bdc10d0008ee.png align="center")

**<mark>Step 9 : Create Jenkinsfile &amp; Dockerfile ih Github repository</mark>**

I have created `java_deploy` repository in my Github account & I have stored sample Java web application project in same repository.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723491700908/9473cd76-17d6-4f54-a69b-1ab09e1549af.png align="center")

Create a docker file in github repository, The name should be `Dockerfile` & Add the below content

```plaintext
# Use an official Tomcat runtime as a parent image
FROM tomcat:9.0.65-jdk11-openjdk

# Copy the WAR file to the webapps directory of Tomcat
COPY target/webapp-tom.war /usr/local/tomcat/webapps/

# Expose port 8080
EXPOSE 8080

# Run Tomcat
CMD ["catalina.sh", "run"]
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723491430117/3c8a508e-67df-468a-8b0f-4556bce1c7da.png align="center")

Create a jenkins file in github repository, The name should be `Jenkinsfile` & Add the below content

```plaintext
pipeline {
    agent any

    environment {
        REMOTE_SSH_CREDENTIALS_ID = 'Slave1'
        REMOTE_HOST = '13.201.85.186'
        DOCKER_IMAGE = 'my-app:latest'
    }

    stages {
        stage('Checkout') {
            steps {
                echo 'Checking out code from GitHub...'
                git url: 'https://github.com/dineshkrish1607/java_deploy.git', branch: 'main'
            }
        }

        stage('Build') {
            steps {
                echo 'Building the project with Maven inside Docker...'
                script {
                    docker.image('maven:3.8.3-openjdk-17').inside {
                        sh 'mvn clean package'
                    }
                }
            }
        }

        stage('Build Docker Image') {
            steps {
                echo 'Building Docker image...'
                script {
                    docker.build(env.DOCKER_IMAGE)
                }
            }
        }

        stage('Deploy to Remote Server') {
            steps {
                echo 'Deploying Docker container to remote server...'
                sshagent([env.REMOTE_SSH_CREDENTIALS_ID]) {
                    sh """
                    ssh -o StrictHostKeyChecking=no ubuntu@${REMOTE_HOST} '
                        docker run -d -p 8080:8080 ${env.DOCKER_IMAGE}
                    '
                    """
                }
            }
        }
    }

    post {
        always {
            echo 'Pipeline completed'
        }
    }
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723491563139/763c3727-64a3-4cd0-8515-b89431cfa869.png align="center")

Now, I have successfully added Java project, Jenkins file and Docker file in my github repository.

**<mark>Step 10 : Create CI/CD pipeline</mark>**

Go to jenkins dashboard &gt; Click on `New Item`

Enter name for pipeline : `Java Deploy` &gt; Select `Pipeline` &gt; Click `OK`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723406719530/687e10a9-c171-45b4-b2fa-e2ac09e4b9a0.png align="center")

Scroll down to the `Pipeline` section

Set the **Definition** to `Pipeline script from SCM` &gt; Select `Git` as the SCM

Enter your `repository URL`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723407561977/eebbbb2e-d695-4d7b-b8e7-5a54e3a18287.png align="center")

Specify the branch `main` &gt; In Script path, enter the name `Jenkinsfile`

Click `Save`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723407652440/72fd5f29-7818-4ef9-925c-9ecff19ef256.png align="center")

In the Jenkins dashboard, navigate pipeline job `Java Deploy`

Click `Build Now` to trigger the pipeline &gt; You can monitor the progress of pipeline

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723490506530/0b0a169d-e2b6-40f6-b5f6-4b762b18983a.png align="center")

Now, Pipeline is successfully completed

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723490563102/c07cc81f-15da-4129-9ea7-744d5d3e90a3.png align="center")

**<mark>Step 11 : Check the Docker Container Status</mark>**

Lists all running containers

```plaintext
docker ps
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723490795150/51b606b1-56fc-4c97-a507-70ac8b3a6c95.png align="center")

Execute the container

```plaintext
docker exec -it [con.name/id] /bin/bash
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723490868291/c6e2fea1-e02f-466c-839f-09335f4a59ee.png align="center")

Go to /usr/local/tomcat/webapps path & Check your application

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723491123074/f7c9b187-69b4-4244-87db-02901da352d2.png align="center")

**<mark>Step 12 : Check &amp; Access the Application URL</mark>**

```plaintext
http://<public ip>:port/context path/
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1723491222415/d8d77377-1793-4f46-9dbf-84590b04fd71.png align="center")

### Conclusion

In this blog, we've explored how to configure a CI/CD pipeline using Jenkins, Maven, and Docker to automate the build and deployment of a Java web application.
