Automating CI/CD for My App with Jenkins, Docker, and GitHub Webhooks π

Table of contents
- π Introduction
- π What is CI/CD and Why Do We Use It?
- βοΈ Prerequisites for Jenkins CI/CD
- π§± Types of Jenkins Pipelines
- π Jenkins Pipeline Structure (Groovy Syntax)
- π‘ What is an Agent in Jenkins?
- π Jenkins Pipeline Stages I Created
- π Trivy & DevSecOps: Security First
- π³ Docker Distroless Image for Smaller Attack Surface
- π Pushing Images to Docker Hub Securely
- π§© Docker Compose for Deployment
- π§Ή Cleaning Up: Avoid Disk Bloat
- π GitHub Webhook Integration
- π§ Email Notifications with SMTP
- β Final Thoughts: A Robust CI/CD Pipeline
- π Whatβs Next?
- π Conclusion

π Introduction
In my journey as a DevOps enthusiast, I recently deep-dived into Jenkins and successfully set up a complete CI/CD pipeline for a banking application. I had already learned Linux, shell scripting, Docker, Docker Compose, and even deployed my app on an AWS EC2 server using distroless images. This time, I took it to the next level by learning CI/CD with Jenkins, automating deployments, integrating with GitHub, and setting up email alerts for pipeline status.
In this blog, Iβll walk you through what I learned, how I did it, and why these practices are essential in the DevOps world.
π What is CI/CD and Why Do We Use It?
CI/CD stands for:
CI (Continuous Integration): Automatically building and testing code every time a developer commits changes to version control (e.g., GitHub).
CD (Continuous Deployment/Delivery): Automatically deploying code to production or staging environments after passing tests.
This process reduces manual intervention, speeds up software delivery, and ensures fewer bugs in production.
With tools like Jenkins, we can automate the entire CI/CD pipeline from cloning the repo to deploying the app seamlessly.
βοΈ Prerequisites for Jenkins CI/CD
To set up a Jenkins-based CI/CD pipeline, I installed the following tools:
β Java (required for Jenkins)
β Jenkins (open-source automation server)
β Docker (to containerize the app)
β Docker Compose (to deploy multi-container apps easily)
π§± Types of Jenkins Pipelines
Jenkins supports two main pipeline types:
1. Declarative Pipeline (the one I used)
Simpler and more structured.
Uses a predefined syntax with
pipeline {}
block.
2. Scripted Pipeline
Uses full Groovy scripting.
Offers more control but requires more code.
β For my project, I chose Declarative Pipeline due to its clean and beginner-friendly syntax.
π Jenkins Pipeline Structure (Groovy Syntax)
Hereβs the basic structure of a declarative pipeline:
pipeline {
agent any
stages {
stage('Code') {
steps {
echo 'Cloning the code...'
}
}
stage('Build') {
steps {
echo 'Building the app...'
}
}
stage('Test') {
steps {
echo 'Running tests...'
}
}
stage('Deploy') {
steps {
echo 'Deploying the app...'
}
}
}
}
π‘ What is an Agent in Jenkins?
Agent defines where the Jenkins pipeline runs. It can be:
agent any
: Run on any available Jenkins agent.agent { label "label_name" }
: Run on a specific node.
π My Setup:
I created a dedicated agent node on an AWS EC2 server to deploy my app. This offloads deployment from the Jenkins master node and allows me to scale deployments across multiple servers.
Benefit: Distributing workload and separating Jenkins from application hosting.
π Jenkins Pipeline Stages I Created
Here are the stages I implemented in my Jenkins pipeline:
Clone β Pulled code from GitHub repository.
Scan β Used Trivy to perform vulnerability scanning (DevSecOps).
Build β Built a Docker image using a distroless Dockerfile.
Test β Placeholder for testing (can be extended with real test cases).
Push β Logged into Docker Hub and pushed the image securely using Jenkins credentials.
Deploy β Pulled the image and deployed it using Docker Compose.
Clean β Cleaned up unused Docker images and containers to save disk space.
π Trivy & DevSecOps: Security First
In the Scan stage, I used Trivy an open-source vulnerability scanner. It scans OS packages, dependencies, and container images.
This integrates DevSecOps into the pipeline, ensuring security is not an afterthought but part of the development process.
π³ Docker Distroless Image for Smaller Attack Surface
I created a distroless Docker image, which contains only the necessary application dependencies no shell, no package manager.
β Benefits:
Smaller image size
Better security
Faster startup time
π Pushing Images to Docker Hub Securely
Instead of hardcoding Docker Hub credentials in my pipeline, I stored them in Jenkins Credentials and accessed them like this:
withCredentials([usernamePassword(credentialsId: 'DockerHubCreds', usernameVariable: 'dockerHubUser', passwordVariable: 'dockerHubPass')]) {
sh "docker login -u $dockerHubUser -p $dockerHubPass"
// push image
}
This keeps secrets safe and follows DevOps best practices.
π§© Docker Compose for Deployment
In the Deploy stage, I used Docker Compose to run multi-container services (like backend + DB).
Example command:
docker compose up -d --build bankapp
Docker Compose makes it easy to define and run multi-container Docker apps using a simple YAML file.
π§Ή Cleaning Up: Avoid Disk Bloat
To avoid Jenkins agents running out of disk space, I added a final Clean stage:
docker system prune -a --force
This removes unused images, containers, and networks.
π GitHub Webhook Integration
I connected my GitHub repo to Jenkins using a Webhook, so every time I push code, Jenkins automatically triggers the pipeline.
β No need to manually trigger builds CI in action!
π§ Email Notifications with SMTP
I configured an SMTP server in Jenkins and used the emailext
plugin to send email alerts:
- If the pipeline is successful or fails, I get an email.
Example from my pipeline:
post {
success {
emailext(
to: 'email',
subject: 'Pipeline is successful',
body: 'Your banking app pipeline ran successfully!'
)
}
failure {
emailext(
to: 'email',
subject: 'Pipeline Failed',
body: 'Please check Jenkins logs for errors.'
)
}
}
β Final Thoughts: A Robust CI/CD Pipeline
By combining everything above, Iβve created a production-grade CI/CD pipeline that:
Automatically builds, tests, and deploys my app
Scans for vulnerabilities
Pushes images securely to Docker Hub
Sends alerts via email
Triggers automatically on code push
π Whatβs Next?
I plan to integrate more advanced testing stages, monitoring.
π Conclusion
This project taught me how CI/CD isn't just about automation, it's about building reliable and scalable workflows. Jenkins remains one of the most powerful tools to get started with.
If you found this helpful, feel free to connect, share your feedback, or ask questions!
Subscribe to my newsletter
Read articles from Atharv Karpe directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
