DevOps Project-39: Secure CI/CD Pipeline on Local Ubuntu Using Jenkins, SonarQube & Trivy (100% Free)
- Authors

- Name
- NotHarshhaa
- GitHub
DevSecOps Project: Secure CI/CD Pipeline on Local Ubuntu Using Jenkins, SonarQube & Trivy (100% Free)
A hands-on DevOps project that brings together Jenkins, SonarQube, and Trivy β all running locally with Docker Compose β to create a cost-free and secure CI/CD pipeline.
π§ Introduction
CI/CD is at the heart of modern DevOps. But what if you could build an end-to-end secure pipeline using only open-source tools β and run everything locally on a single Ubuntu server?
Thatβs exactly what I did β
In this tutorial, Iβll walk you through setting up a complete DevSecOps pipeline where:
π§ Jenkins handles the automation
π§ͺ SonarQube ensures code quality
π‘οΈ Trivy scans for vulnerabilities
π³ Docker Compose manages all containers
π₯οΈ Even the deployment host is the same server, making this setup incredibly efficient and minimal
No external VMs, no cloud cost, no complexity β just pure DevOps learning π»β¨
π» System Requirements
OS: Ubuntu 20.04+
RAM: 8 GB+
Tools: Docker, Docker Compose
Internet access for pulling images
π§± Step 1: Clone the Project & Launch Jenkins + SonarQube with Docker Compose
Before setting up our CI/CD magic, letβs get the project ready by cloning the repository and initializing the required directories and SSH keys.
π 1οΈβ£ Clone the Repository
Start by cloning the DevSecOps project repo that contains our pre-configured docker-compose.yaml and helper scripts:
git clone https://github.com/NotHarshhaa/DevOps-Projects/tree/master/DevOps-Project-39/cicd-jenkins
cd cicd-jenkins
Press enter or click to view image in full size

π 2οΈβ£ Run start.sh to Prepare the Jenkins Agent
This script does two important things:
π Creates required directories (
jenkins_home,jenkins_agent,jenkins_agent_keys)π Generates SSH key pairs for Jenkins master β agent authentication
chmod +x setup.sh
sh setup.sh
Press enter or click to view image in full size

β After this, your system is ready to launch the services!
π How This Docker Compose Setup Works (All-in-One CI/CD Stack)
This Docker Compose file orchestrates a fully functional DevSecOps pipeline stack β all running locally, isolated in a shared network β and ready to automate builds, scans, and deployments π₯
version: "3.8"
services:
# π§ Jenkins Master
jenkins-master:
image: jenkins/jenkins:lts-jdk17
container_name: jenkins
restart: unless-stopped
user: 1000:1000
ports:
- "8080:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home:rw
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
environment:
- JAVA_OPTS=-Dhudson.security.csrf.GlobalCrumbIssuerStrategy=true -Djenkins.security.SystemReadPermission=true
networks:
- jenkins_network
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:size=2G
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/login || exit 1"]
interval: 1m30s
timeout: 10s
retries: 3
# π§ Jenkins SSH Agent
jenkins-agent:
image: jenkins/ssh-agent
container_name: jenkins-agent
restart: unless-stopped
expose:
- "22"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- jenkins_agent:/home/jenkins/agent:rw
- type: bind
source: ./jenkins_agent_keys
target: /home/jenkins/.ssh
read_only: true
environment:
- SSH_PUBLIC_KEY_DIR=/home/jenkins/.ssh
networks:
- jenkins_network
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp:size=2G
# π§ SonarQube
sonarqube:
container_name: sonarqube
image: sonarqube:lts-community
restart: unless-stopped
depends_on:
- sonar_db
ports:
- "9001:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://sonar_db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- sonarqube_conf:/opt/sonarqube/conf
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
- sonarqube_temp:/opt/sonarqube/temp
networks:
- jenkins_network
# π Postgres for SonarQube
sonar_db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonar
volumes:
- sonar_db:/var/lib/postgresql
- sonar_db_data:/var/lib/postgresql/data
networks:
- jenkins_network
# π Shared Network
networks:
jenkins_network:
driver: bridge
# πΎ Volumes
volumes:
jenkins_home:
jenkins_agent:
sonarqube_conf:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
sonarqube_temp:
sonar_db:
sonar_db_data:
π οΈ Jenkins Master (jenkins-master)
π¦ Image: Uses
jenkins/jenkins:lts-jdk17π Ports:
8080: Jenkins web UI50000: For connecting inbound agentsπΎ Volumes:
jenkins_home: Persists Jenkins jobs, config, and plugins/var/run/docker.sock: Lets Jenkins build and run Docker containers/usr/bin/docker: Gives Jenkins CLI access to Docker commandsπ§ͺ Health Check:
Automatically checks service availability via a
curllogin probeπ Hardened Settings:
read_only: true: Makes the container filesystem immutabletmpfs: Stores/tmpin RAM for better performance and safetyno-new-privileges: Prevents privilege escalation inside the container
βοΈ Jenkins SSH Agent (jenkins-agent)
π¦ Image: Uses
jenkins/ssh-agent(for connecting back to master)π SSH Access:
Mounts SSH keys from
jenkins_agent_keysto enable secure agent communicationπΎ Volumes:
jenkins_agent: Stores agent workspace data/usr/bin/docker+ Docker socket: Enables builds inside the agent containerπ‘οΈ Security First:
read_only: true+tmpfs: Isolates temp files in RAMno-new-privileges: Blocks processes from elevating access
π§ SonarQube (sonarqube)
π¦ Image:
sonarqube:lts-communityπ Port Mapping:
Exposed as
localhost:9001 β container:9000π Connects to PostgreSQL (
sonar_db)Configured via
SONAR_JDBC_URLand credentialsπΎ Volumes:
Persist configuration, extensions, data, logs, and temp files
π Depends On:
Ensures PostgreSQL container starts before SonarQube
π PostgreSQL Database (sonar_db)
π¦ Image:
postgres:15π― Purpose: Backend database for SonarQube code analysis data
π Environment Variables:
Sets DB name, user, and password for SonarQube integration
πΎ Volumes:
sonar_dbandsonar_db_data: Persist DB schema and data
π Common Docker Network: jenkins_network
All containers share a custom bridge network, enabling secure internal DNS resolution and private communication between services (like jenkins β agent β sonarqube β postgres).
π³ 3οΈβ£ Launch Jenkins + SonarQube + PostgreSQL with Docker Compose
Now that everything is set, fire up the full stack:
docker-compose up -d
Press enter or click to view image in full size

β Verify Container Status After Launch
Once youβve started the stack using docker compose up -d, youβll want to make sure everything is running properly.
π§ͺ Run this command to check the status of all containers:
docker ps
Press enter or click to view image in full size

β³ Give Jenkins Some Timeβ¦
β οΈ Note: Jenkins Master takes a bit of time to fully initialize β especially on the first run when it sets up plugins and internal directories.
β²οΈ Wait 1β2 minutes, then run docker ps again.
Press enter or click to view image in full size

You should see:
π’
jenkinscontainer: showinghealthyπ’
jenkins-agentcontainer: upπ§
sonarqube: should also be healthy and accessible atlocalhost:9001
β Once all containers are up and healthy, youβre ready to configure Jenkins and start building pipelines!
π Step 4: Access Jenkins Web Interface
Your Jenkins Master is now running β letβs unlock the power of automation! π
π₯οΈ Open your browser and go to:
http://localhost:8080
Press enter or click to view image in full size

Youβll be greeted by the Jenkins Setup Wizard π§ββοΈ
- π Enter the initial admin password
To retrieve the initial admin password for login run the below command
docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
Press enter or click to view image in full size

Follow the guided setup: install recommended plugins, create your admin user
Press enter or click to view image in full size

Press enter or click to view image in full size

Once it finished will ask for configure admin user.Click save & continue
Press enter or click to view image in full size

Press enter or click to view image in full size

Once you completed we can see the jenkins dashboard as below
Press enter or click to view image in full size

π§± Step 2: Configure jenkins agent for build
π 1οΈβ£ Add SSH Credentials for Jenkins Agent
Now letβs securely configure the SSH authentication so the Jenkins Master can talk to the Jenkins Agent π
Navigate to your Jenkins dashboard.
Click on Manage Jenkins.
Select Credentials.
Under (global), click Add Credentials.
Fill in the form:
Kind: SSH Username with private key
Scope: Global
Username: jenkins
Private Key: Enter directly
Key: Paste the contents of the
id_rsafile located inside thejenkins_agent_keysfolder. This key is automatically generated during the setup process when you run thesetup.shscript.
Press enter or click to view image in full size

ID: can give some name to identify the credential,here i am giving build-agent
Description: SSH key for Jenkins agent
Click OK to save.

π Step 4: Connect Agent to Jenkins Master
In Jenkins, go to Manage Jenkins > Manage Nodes and Clouds.
Click New Node.
Enter a name (e.g.,
agent), select Permanent Agent, and click create
Press enter or click to view image in full size

- Configure the node:
Remote root directory:
/home/jenkins/agentLabels:
agentLaunch method: Launch agents via SSH
Host:
jenkins-agent(matches the Docker service name)Credentials: Select the credential that you have created earlier
Host Key Verification Strategy: Manually trusted key verification Strategy
Click Save
Press enter or click to view image in full size


Verify Connection:
- Jenkins will attempt to connect to the agent. If successful, the agentβs status will show as Connected.
Press enter or click to view image in full size

Step 3:Configure Jenkins Agent SSH Key for Remote Host Access
Since we already generated the SSH key pair during the Jenkins setup (via setup.sh), we can reuse the same private key for connecting to the remote host.(in our case it is the same local ubuntu server where we running containers )
β
Just copy the public key to your host machineβs authorized_keys.
On your host machine, run the following commands:
cat /home/user/devops-projects/cicd-jenkins/jenkins_agent_keys/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Press enter or click to view image in full size

π§ This allows Jenkins (via the agent) to SSH into the host machine securely using the existing key β
π 2οΈβ£ Add SSH Credentials for Remote Host Deployment
These credentials allow Jenkins to SSH into your remote host and trigger Docker Compose commands during deployment.
β‘οΈ Go to Manage Jenkins β Credentials β (Global) β Add Credentials
Then fill out the following fields:
Kind: SSH Username with private key
Scope: Global
Username:
user(or your actual host system username)Private Key: Enter directly β paste the content of
id_rsafromjenkins_agent_keysfolder (generated bysetup.sh)ID (optional):
deploy-server-sshDescription: Remote host SSH for Docker Compose deployment
π Plugin Power-Up: Install Essential Jenkins Plugins π
βοΈ Go to: Manage Jenkins β Plugins β Available Plugins*β Search and* Install without restart for each listed plugin below.
1οΈβ£ Eclipse Temurin Installer
π§ Installs and manages JDK versions for your build environments
2οΈβ£ SonarQube Scanner
π Integrates Jenkins with SonarQube to analyze code quality and detect bugs
3οΈβ£ NodeJS Plugin
π Allows Jenkins to install and use specific Node.js versions in pipelines
4οΈβ£ Docker Plugin Suite (Install all individually) π³
Enables full Docker support in Jenkins β from simple builds to full pipelines
β Docker Plugin
β Docker Commons
β Docker Pipeline
β Docker API
β Docker Build Step
5οΈβ£ SSH Agent Plugin
π Use SSH credentials securely to connect and execute on remote machines
Press enter or click to view image in full size

π§ Step 4: Access & Secure Your SonarQube Dashboard
π SonarQube is now up and running on port 9001
π Open your browser and visit:
π http://localhost:9001/
π Login using default credentials:
Username:
adminPassword:
admin
β οΈ Important:
Youβll be prompted to change the default password on your first login.
Make sure to choose a strong one! π
Press enter or click to view image in full size

Step5: Integrating Jenkins with SonarQube
π 1: Create a Global Token in SonarQube
Log in to SonarQube with the admin user
In the top right corner, click your username(Here it is Administrator)β choose βMy Accountβ.
Press enter or click to view image in full size

Go to the βSecurityβ tab.
Under Generate Tokens:
Name: enter something like
jenkins-global-tokenType: leave it as User Token
Expires In: choose
No expiration(recommended for CI usage)
- Click Generate, and copy the token (you wonβt be able to see it again later).
β This token allows Jenkins to push analysis results to any project that the user has access to.
Press enter or click to view image in full size

After previous step, youβll see the generated token. Save it somewhere to not loose. Weβll need that for later.
π Why Use a Global Token?
π Reusable across all projects β no need to generate separate tokens per project
π§Ή Easy to manage β one place to rotate/update
β Secure β stored in Jenkins as a credential (not hardcoded)
βοΈ Scalable β works even as your pipeline or project count grows
π§± Step 2: Create the Project (Using the Global Token)
Navigate to Projects β Create Project.
Select Manually.
Press enter or click to view image in full size

3.Fill:
Project Key: blog-app
Display Name: blog-app
Main branch name: In my case it is main.But in some projects it could be master or dev as well
Press enter or click to view image in full size

4.On the next screen, when youβre asked:
How do you want to analyze your project?**β Choose:
Locally
- It will now prompt:
Use existing token**π Paste your global token here
π’ DO NOT click Generate Token β instead, choose βUse existing tokenβ and paste the global one you created in Step 1.
This completes the project setup and links your global token to it.

Press enter or click to view image in full size

Note: You can see the Run analysis on your project options after giving the token.Just ignore the further steps .Will add the necessary commands in Jenkinsfile
π§Ύ 3. Add SonarQube Token to Jenkins Credentials
In Jenkins, go to
Manage Jenkins>Credentials.Select the appropriate domain (e.g.,
(global)).Click Add Credentials.
Choose Secret text as the kind.
Paste the SonarQube token into the
Secretfield that we created from the step Create a Global Token in SonarQubeProvide an ID (e.g., sonar-token) and a description.
Click Create to save.
Press enter or click to view image in full size

βοΈ 4. Configure SonarQube Server in Jenkins
Navigate to
Manage Jenkins>Configure System.Scroll down to the SonarQube servers section.
Click Add SonarQube.
Provide a name for the server (e.g. sonar-server).
Enter the SonarQube server URL (
http://sonarqube:9000).
β Use the Docker container name
sonarqubeβ this works because both Jenkins and SonarQube are running on the same Docker Compose network (jenkins_network), and Docker handles the DNS resolution automatically
6.Server authentication token:
Select the credential ID you created earlier β e.g., sonar-token
7.Check Enable injection of SonarQube server configuration as build environment variables.
β βEnable injection of SonarQube server configuration as build environment variablesβ
When checked, Jenkins automatically injects environment variables like:
SONAR_HOST_URL
SONAR_AUTH_TOKEN
SONAR_SCANNER_HOMEThese can then be used inside shell scripts or pipeline steps without hardcoding*.Click* Save to apply the changes.
Press enter or click to view image in full size

6. Installing Required Tools in Jenkins
To make Jenkins ready for CI/CD magic β¨, we need to equip it with essential tools. These tools empower Jenkins to build, test, scan, and deploy applications across the pipeline.
π Navigate to:
Jenkins Dashboard β Manage Jenkins β Global Tool Configuration
Now, configure the following:
π 1. π§ͺ SonarQube Scanner
β Required for performing static code analysis on your project directly from Jenkins
π§ Steps to configure:
Navigate to the SonarQube Scanner section β Click β Add SonarQube Scanner
π·οΈ Name: sonar-scanner
β
Check: Install automatically
π½ Installer source: Install from Maven Central
π Version: 7.0.2.4839 (or latest available)
π Jenkins will now auto-download and manage the SonarQube Scanner version needed for your pipeline.
π§ This ensures that your pipeline always has a ready-to-go scanner for SonarQube analysis without needing to install anything manually on your host.
Press enter or click to view image in full size

2.β JDK 21 (Temurin)
β Required to compile Java-based projects and run tools like SonarQube Scanner in Jenkins
π§ Steps to configure:
Navigate to the JDK section β Click β Add JDK
π·οΈ Name:
jdk21β Check: Install automatically
π½ Installer source: Install from adoptium.net
π Select version:
21.0.4(or latest available under JDK 21)
π§ This setup ensures Jenkins downloads and uses Java 21 from the official Adoptium build
Press enter or click to view image in full size

3.π© NodeJS 21.0.0
β Required for building frontend applications (React, Vue, Angular) or running JavaScript-based tools in Jenkins
π§ Steps to configure:
Scroll to the NodeJS section β Click β Add NodeJS
π·οΈ Name:
node21β Check: Install automatically
π½ Installer source: Install from nodejs.org
π Select version:
21.0.0
π§ This configuration allows Jenkins to download and manage Node.js v21.0.0 directly from the official Node.js website
Press enter or click to view image in full size

4.π³ Docker (Latest)
β Essential for building, running, and scanning Docker containers directly from Jenkins pipelines
π§ Steps to configure:
Scroll to the Docker section β Click β Add Docker
π·οΈ Name:
dockerβ Check: Install automatically
π½ Installer source: Download from docker.com
π Select version: (latest available or your preferred Docker version)
π§ With this setup, Jenkins automatically installs Docker from the official source β no manual setup or system-level install required.
- Ensure Docker is already installed on your system (
/usr/bin/docker)
π Youβve already mounted the Docker socket in your Jenkins Compose file, so this config links Jenkins with the host Docker engine.
Press enter or click to view image in full size

Apply and Save:
- Once all tools are configured, click Apply and Save.
Step 7: Configure Essential Credentials in Jenkins for Secure CI/CD
π§Ύ 1. π Generate a Docker Hub Access Token
Go to: Docker Hub β Account Settings β Security β Access Tokens
Click β βNew Access Tokenβ
Give it a meaningful name (e.g.,
jenkins-ci)Click Generate
π Copy the token (you wonβt see it again!)
Press enter or click to view image in full size

π§° 2. πΌ Add the Token to Jenkins Credentials
Go to your Jenkins Dashboard:
β‘οΈ Manage Jenkins β Credentials β Global Credentials (unrestricted) β Add Credentials
π Select: Kind:
Secret textβοΈ Secret: (Paste the Docker token here)
π·οΈ ID:
docker-hub-token(or any unique identifier)π¬ Description:
Docker Hub Personal Access Token for Jenkins
β Create it!
Press enter or click to view image in full size

π οΈ Step-8:Grant Docker Access to Jenkins
To enable Jenkins (inside the container) to communicate with Docker on the host:
sudo chmod 666 /var/run/docker.sock
Press enter or click to view image in full size

β οΈ Why this is needed?*
This sets read/write permissions on the Docker socket so Jenkins containers can:*
π³ Build Docker images
π Scan them with Trivy
π Push to Docker Hub
π‘ Note*: This is safe for* local testing environments*, but* not recommended for production*.*
π About the Application: Wanderlust β A 3-Tier Web App
π§ Wanderlust is a lightweight 3-tier web application designed to demonstrate full CI/CD automation using open-source DevOps tools. It features:
π¦ Architecture:
Frontend: A modern web UI built with ReactJS (Node.js 21), offering a clean and responsive interface for user interactions.
Backend: A RESTful API developed using Node.js and Express.js, handling business logic and communication with the database.
Database: MongoDB used as the NoSQL data store for posts or travel-related content.
π Set Up Your Jenkins CI/CD Pipeline β Automation Begins Here!
Now that your DevOps environment is all set π―, itβs time to automate your entire workflow β from code checkout to deployment β using a Jenkins pipeline.
π‘ What will this pipeline do?
β
Clone your code from GitHub
β
Run static code analysis via SonarQube
β
Perform vulnerability scans with Trivy
β
Build & push Docker images
β
Deploy the app β hands-free!
Step 9π Letβs Create the Pipeline Job
π₯οΈ Navigate to Jenkins Dashboard:
β Click on βNew Itemβ
π·οΈ Name your project β e.g.,
wanderlust-deployπ§± Choose βPipelineβ as the project type
β Click OK to continue
Press enter or click to view image in full size

Define Pipeline Syntax:
- In the Pipeline section, select Pipeline script and add the following pipeline code:
pipeline {
agent { label 'agent' }
tools {
jdk 'jdk21'
nodejs 'node21'
}
environment {
IMAGE_TAG = "${BUILD_NUMBER}"
BACKEND_IMAGE = "NotHarshhaa/wanderlust-backend"
FRONTEND_IMAGE = "NotHarshhaa/wanderlust-frontend"
}
stages {
stage('SCM Checkout') {
steps {
git branch: 'main', url: 'https://github.com/NotHarshhaa/devops-projects.git'
}
}
stage('Install Dependencies') {
steps {
dir('wanderlust-3tier-project/backend') {
sh "npm install || true"
}
dir('wanderlust-3tier-project/frontend') {
sh "npm install"
}
}
}
stage('Run SonarQube') {
environment {
scannerHome = tool 'sonar-scanner'
}
steps {
withSonarQubeEnv('sonar-server') {
sh """
${scannerHome}/bin/sonar-scanner \
-Dsonar.projectKey=blog-app \
-Dsonar.projectName=blog-app \
-Dsonar.sources=wanderlust-3tier-project
"""
}
}
}
stage('Docker Build') {
steps {
dir('wanderlust-3tier-project') {
sh '''
docker build -t ${BACKEND_IMAGE}:${IMAGE_TAG} ./backend
docker build -t ${FRONTEND_IMAGE}:${IMAGE_TAG} ./frontend
'''
}
}
}
stage('Scan with Trivy') {
steps {
script {
def images = [
[name: "${BACKEND_IMAGE}:${IMAGE_TAG}", output: "trivy-backend.txt"],
[name: "${FRONTEND_IMAGE}:${IMAGE_TAG}", output: "trivy-frontend.txt"]
]
for (img in images) {
echo "π Scanning ${img.name}..."
sh """
mkdir -p wanderlust-3tier-project
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v \$HOME/.trivy-cache:/root/.cache/ \
-v \$WORKSPACE/wanderlust-3tier-project:/scan-output \
aquasec/trivy image \
--scanners vuln \
--severity HIGH,CRITICAL \
--exit-code 0 \
--format table \
${img.name} > wanderlust-3tier-project/${img.output}
"""
}
}
}
}
stage('Push to Docker Hub') {
steps {
withCredentials([string(credentialsId: 'docker-hub-token', variable: 'DOCKER_TOKEN')]) {
sh '''
echo "${DOCKER_TOKEN}" | docker login -u rjshk013 --password-stdin
docker push ${BACKEND_IMAGE}:${IMAGE_TAG}
docker push ${FRONTEND_IMAGE}:${IMAGE_TAG}
'''
}
}
}
stage('Remote Deploy on Host with Docker Compose') {
steps {
sshagent(credentials: ['deploy-server-ssh']) {
sh '''
echo "π Deploying on host with docker compose..."
ssh -o StrictHostKeyChecking=no user@172.18.0.1 '
cd /home/user/devops-projects/wanderlust-3tier-project &&
docker compose build &&
docker compose up -d
'
'''
}
}
}
}
post {
always {
archiveArtifacts artifacts: 'wanderlust-3tier-project/trivy-*.txt', fingerprint: true
}
}
}
π οΈ Understanding the Jenkinsfile (Wanderlust CI/CD Pipeline)
This Jenkinsfile automates the complete build β scan β deploy lifecycle of your Wanderlust project.
Hereβs a step-by-step overview of what it does:
Press enter or click to view image in full size

π₯ Key Highlights
Secure Build: Code quality is validated by SonarQube before proceeding to deployment β
Security First: Images are scanned by Trivy before pushing to Docker Hub π‘οΈ
Fully Automated: No manual steps β from Git pull to live deployment π
Secrets Handling: Docker Hub credentials and SonarQube token are injected via Jenkins Credentials Manager π
Press enter or click to view image in full size

π§ Update Jenkinsfile with Your Values
Before using the pipeline, replace the following placeholders with your own values:
rjshk013 β your actual Docker Hub username
https://github.com/rjshk013/devops-projects.gitβ use the provided repo or your own cloned GitHub repouser@172.18.0.1-Replace with your host username & ip
Thatβs it β just plug in your details and youβre good to go! π
π 1οΈβ£0οΈβ£ Triggering the Pipeline & Viewing Results
Once your Jenkins pipeline is fully configured, itβs time to fire it up! π₯
π οΈ Steps to Run the Pipeline:
π Go to the Jenkins Dashboard and click on your job (e.g., wanderlust-deploy).
βΆοΈ Click βBuild Nowβ on the left panel to trigger the pipeline.
π Navigate to βBuild Historyβ, and click on the latest build number (e.g., #1).
π In the build details page:
β Click Pipeline Steps or Pipeline Overview to visualize each stage.
π₯οΈ Click Console Output to follow the logs in real-time β great for debugging and validation.
Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size

β 1οΈβ£1οΈβ£ Post-Pipeline Verification: Confirm Everything Worked! π΅οΈββοΈ
After the pipeline runs successfully, itβs time to verify each key milestone to ensure your CI/CD process worked perfectly.
π³ Docker Image Push Confirmation
β Go to your Docker Hub repository.
π Navigate to:
wanderlust-backendwanderlust-frontend
π Check if the latest image tags (build numbers) are successfully listed and match the ones from the Jenkins pipeline.
Press enter or click to view image in full size

π§ SonarQube Code Quality Analysis
π Open your browser and go to:http://localhost:9001 (or your configured SonarQube URL)
π Navigate to:
Projectsβblog-app
β You should see a recent analysis with quality gate status, bugs, code smells, duplications, etc.
Press enter or click to view image in full size

Press enter or click to view image in full size

π‘οΈ Trivy Vulnerability Scan
π Go back to Jenkins UI β your job β latest build β Artifacts
π Youβll find files like:
trivy-backend.txttrivy-frontend.txt
π Open them and look for:
Severity levels:
CRITICAL,HIGHConfirm no critical issues OR review and mitigate them accordingly.

π§ͺ 1οΈβ£2οΈβ£ Test the Deployed Application Locally
π Once your CI/CD pipeline has completed successfully, your application is now live and accessible on your host machine. Hereβs how to verify:
π Access Frontend:
π Open your browser and go to:http://localhost:5173/
You should see your React-based frontend app running π
Press enter or click to view image in full size

π οΈ Access Backend (API):
π Open another tab and hit:http://localhost:5000/

π³ Verify Running Containers on Host Machine
To ensure both your frontend and backend services are up and running after deployment, run the following command on your host terminal:
docker ps
Press enter or click to view image in full size

π GitHub Repository
ποΈ You can find the complete source code, Jenkinsfile, Docker Compose setup, and scripts used in this article right here:
π GitHub β Wanderlust 3-Tier DevSecOps CI/CD Project
β Conclusion: Your DevSecOps Lab Is Now Live π
Youβve just built a real-world CI/CD pipeline that:
π§ Automates code building and testing with Jenkins
π§ Ensures code quality through SonarQube
π‘οΈ Scans for vulnerabilities using Trivy
π³ Runs entirely in Docker Compose
π₯οΈ Deploys applications seamlessly on the same local server
And the best part? You did it all with zero cloud cost β 100% open-source, local, and production-grade ready! π―
π― Whatβs Next?
π§ͺ Add unit and integration tests for better quality gates
βοΈ Try extending this setup to a cloud provider like AWS or Azure
π Integrate monitoring tools like Prometheus and Grafana
π¦ Explore Kubernetes and Helm for container orchestration
This setup isnβt just a tutorial β itβs a launchpad into real-world DevOps workflows. Now youβre equipped to experiment, expand, and evolve your own secure software delivery system ππ»
π οΈ Author & Community
This project is crafted by Harshhaa π‘.
Iβd love to hear your feedback! Feel free to share your thoughts.
π§ Connect with me:
π’ Stay Connected
