End-to-End Docker Project with Jenkins CI/CD | Deploying a Node.js App with Security Scans

Introduction

This project demonstrates how to build a complete DevOps pipeline for a Node.js application using Jenkins, Docker, Trivy, SonarQube, and OWASP security checks. The pipeline automates every step from pulling the code from GitHub to deploying a secure Docker container.

You will learn how to:

  • Automatically check out code and analyze it for bugs and code quality with SonarQube

  • Install dependencies and scan them for security risks using OWASP best practices

  • Build and scan Docker images for vulnerabilities with Trivy

  • Push secure Docker images to Docker Hub and deploy them

This project helps you create an automated, secure, and reliable workflow to deliver high-quality applications faster.

Step-by-Step Process to Deploy the Application:

Step 1: Launch EC2 Instance

Start by launching an EC2 instance on AWS. I used a t2.large instance and named it DOCKER PROJECT.

  • OS: Amazon Linux 2

  • Instance Type: t2.large

  • Opened port 22 for SSH access

Once it's running, note the public IP address — you'll need it to connect via SSH.

Step 2: Install Jenkins, Git, Docker & Trivy

To save time and streamline setup, I created a shell script jenkins.sh to install Git, Jenkins, Java, and Docker in one go.

#STEP-1: INSTALLING GIT
yum install git -y

#STEP-2: GETTING THE REPO (jenkins.io --> download --> redhat)
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade -y
# Add required dependencies for the jenkins package
sudo yum install fontconfig java-21-openjdk -y
sudo yum install jenkins -y
sudo systemctl daemon-reload

#STEP-3: DOWNLOAD JAVA17 AND JENKINS
yum install java-17-amazon-corretto -y
yum install jenkins -y

#STEP-4: RESTARTING JENKINS
systemctl start jenkins.service
systemctl status jenkins.service

#STEP-5: INSTALL DOCKER
yum install docker -y
systemctl start docker

Then run it:

sh jenkins.sh

This script automates the setup for Jenkins, Git, Java, and Docker on your EC2 instance.

You can see the Jenkins is active and running, access Jenkins using the IP address and port number 8000

Check if Git and Docker are installed properly.

To let Jenkins run Docker commands, you need to set proper permissions on the Docker socket.

chmod 777 /var/run/docker.sock

⚠️ Note: This is fine for testing, but not recommended for production.
A more secure approach is to add the Jenkins user to the Docker group

Install Trivy:

wget https://github.com/aquasecurity/trivy/releases/download/v0.18.3/trivy_0.18.3_Linux-64bit.tar.gz
tar zxvf trivy_0.18.3_Linux-64bit.tar.gz
sudo mv trivy /usr/local/bin/

At this point, the trivy command might not work if the path isn't set properly.

Fix the PATH:

# Show hidden files
ll -a

# Open .bashrc
vim ~/.bashrc

# Add this line at the end
export PATH=$PATH:/usr/local/bin/

# Save and apply changes
source ~/.bashrc

Step 3 : Install Jenkins Plugins

  • SonarQube Scanner – for code quality analysis

  • NodeJS – to support Node-based applications

  • OWASP Dependency-Check – to detect vulnerable dependencies

  • Docker Pipeline – enables Docker support in Jenkins pipelines

  • AdoptOpenJDK (Temurin) – for Java-based environments

How to install them:

  1. Go to Jenkins Dashboard

  2. Click Manage Jenkins → Manage Plugins

  3. In the Available tab, search for each plugin

  4. Select them and click Install without restart

💡 Restart Jenkins after installation to ensure all plugins load properly.

Step 4: Set Up SonarQube with Docker

docker run -d --name sonar -p 9000:9000 sonarqube:lts-community

This pulls the latest LTS community version of SonarQube and runs it in a container named sonar

Access the SonarQube using the IP address with port number 9000. Username: admin Password: admin

Create a dummy project to access the sonar dashboard

Step 4: Configure Jenkins Credentials and Tools

Now that SonarQube is up and running, let’s configure it with Jenkins by adding credentials, setting up the server, and linking the scanner.

Generate SonarQube Token:

  1. Go to your SonarQube dashboard

  2. Navigate to: Administration → Security → Users → Tokens

  3. Click Generate Token, give it a name and copy the token

Add Credentials in Jenkins:

  1. Go to Jenkins Dashboard → Manage Jenkins → Credentials

  2. Choose Global credentials and click Add Credentials

  3. Set:

    • Kind: Secret text

    • Secret: Paste the SonarQube token

    • ID: sonar

    • Description: sonar password

Configure SonarQube Server in Jenkins:

  1. Go to Manage Jenkins → Configure System

  2. Scroll to SonarQube servers

  3. Click Add SonarQube

    • Name: mysonar

    • Server URL: http://<your-sonarqube-ip>:9000

    • Server authentication token: Select the sonar password you just added

Add Webhook in SonarQube:

  1. Go to SonarQube → Administration → Configuration → Webhooks

  2. Click Create

    • Name: Jenkins

    • URL: http://<your-jenkins-ip>:8080/sonarqube-webhook/

Set up SonarQube scanner, NodeJS (node16), JDK (jdk17), and OWASP DP-Check

Step 5: Declarative Jenkins Pipeline

pipeline {
    agent any

    tools {
        jdk 'jdk17'
        nodejs 'node16'
    }

    environment {
        SCANNER_HOME = tool 'mysonar'
    }

    stages {
        stage ("Clean") {
            steps {
                cleanWs()
            }
        }

        stage ("Code") {
            steps {
                git "https://github.com/PasupuletiBhavya/Zomato-Project.git"
            }
        }

    }
}

BUILD THIS PIPELINE

This confirms that the Zomato-Project has been cloned successfully into:

/var/lib/jenkins/workspace/MyDeployment/
stage("SCAN") {
    steps {
        withSonarQubeEnv('mysonar') {
            sh '''
                $SCANNER_HOME/bin/sonar-scanner \
                -Dsonar.projectName=zomato \
                -Dsonar.projectKey=zomato
            '''
        }
    }
}

SAVE AND BUILD

After successful build open SonarQube to check for bugs or vulnerabilities

stage ("Quality Gates") {
    steps {
        script {
            waitForQualityGate abortPipeline: false, credentialsId: 'sonar-token'
        }
    }
}

This stage checks whether the code passed all the SonarQube quality checks. If it fails and abortPipeline is set to true, Jenkins will stop the build.

stage ("Install dependencies") {
    steps {
        sh 'npm install'
    }
}

This stage installs all required Node.js packages using npm install. This uses the package.json file to fetch and install all project dependencies before the build or run steps begin.

After running npm install, the node_modules folder appears, confirming that dependencies were installed successfully.

This part of the pipeline covers security checks, Docker build, image push, scan, and app deployment.

Final Pipeline Stages

stage ("OWASP") {
    steps {
        dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'Dp-Check'
        dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
    }
}

stage ("Trivy scan") {
    steps {
        sh "trivy fs . > trivyfs.txt"
    }
}

stage ("Build Dockerfile") {
    steps {
        sh 'docker build -t image1 .'
    }
}

stage("Docker Build & Push") {
    steps {
        script {
            withDockerRegistry(credentialsId: 'docker-password') {
                sh "docker tag image1 bhavyap007/dockerproject:zoamto"
                sh "docker push bhavyap007/dockerproject:zoamto"
            }
        }
    }
}

stage ("Scan image") {
    steps {
        sh 'trivy image bhavyap007/dockerproject:zoamto'
    }
}

stage ("Deploy") {
    steps {
        sh 'docker run -d --name zomato -p 3000:3000 bhavyap007/dockerproject:zoamto'
    }
}

All stages executed successfully, completing the CI/CD pipeline from code to container to deployment.

After building and tagging the Docker image, it was successfully pushed to Docker Hub under the repository:

The image is now public and can be pulled and deployed from anywhere using:

docker pull bhavyap007/dockerproject:zomato

Access your application with your IP address and port number 3000

Final Pipeline Flow Summary

  1. Launch EC2 instance and open required ports.

  2. Install Jenkins, Git, Docker, Trivy, and OWASP tools.

  3. Configure Jenkins plugins and add SonarQube token.

  4. Run SonarQube using Docker and link it to Jenkins.

  5. Create Jenkins pipeline with these stages:

    • Clean workspace

    • Clone code from GitHub

    • Run SonarQube scan

    • Wait for Quality Gate result

    • Install Node.js dependencies

    • Run OWASP and Trivy scans

    • Build and push Docker image

    • Scan Docker image

    • Deploy container

  6. App runs on port 3000 — deployment successful!

What I Learned

  • How to set up a full CI/CD pipeline using Jenkins and Docker.

  • Installing and configuring tools like SonarQube, Trivy, and OWASP Dependency-Check.

  • Writing a Declarative Jenkins Pipeline from scratch.

  • Scanning code and Docker images for vulnerabilities.

  • Automating Docker image builds, pushes to Docker Hub, and deployments.

  • How all DevOps tools connect together to ensure smooth, secure delivery


This hands-on Docker CI/CD project gave me a deeper understanding of how real-world DevOps pipelines work — from source code management to automated testing, security scanning, containerization, and deployment. It brought together tools like Jenkins, Docker, SonarQube, Trivy, and OWASP Dependency-Check in a complete flow.

For anyone starting out in DevOps, building a pipeline like this is one of the best ways to gain practical, resume-worthy experience.

If this article helped you in any way, your support would mean a lot to me 💕 — only if it's within your means.

Let’s stay connected on LinkedIn and grow together!

💬 Feel free to comment or connect if you have questions, feedback, or want to collaborate on similar projects.

20
Subscribe to my newsletter

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

Written by

Bhavya Pasupuleti
Bhavya Pasupuleti