Jenkins CI/CD Pipeline Tutorial (2026): Real DevOps Projects with AWS EC2 Deployment & Custom Domain Setup
⚙️ JENKINS CI/CD MASTERY 2026
Jenkins Pipeline Tutorial
Complete 8-Chapter Course
Build CI/CD with Real Projects, GitHub → Jenkins → Docker → AWS EC2 → Custom Domain. Company-grade pipeline from scratch.
📝 Code Push
→
⚙️ Jenkins Build
→
🧪 Auto Test
→
🐳 Docker Image
→
☁️ AWS EC2
→
🌐 Custom Domain
8CHAPTERS
12+REAL PROJECTS
⚡CI/CD AUTOMATION
🌍CUSTOM DOMAIN
Chapter 1: Jenkins Introduction & Installation
📖 Definition: Jenkins is an open-source automation server written in Java. It automates building, testing, and deploying software. 1800+ plugins, distributed builds, pipeline as code.
Developer → Git Push → Jenkins Build → Test → Deploy → Production
$ sudo apt update
$ sudo apt install openjdk-11-jdk -y
$ curl -fsSL https://pkg.jenkins.io/debian-stable/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-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
$ sudo apt update && sudo apt install jenkins -y
$ sudo systemctl start jenkins && sudo systemctl enable jenkins
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
🔍 Step-by-Step: Java 11 required. Jenkins repo key added for secure downloads. Jenkins runs on port 8080. InitialAdminPassword used for first-time setup.
📁 CASE PROJECT 1.1: Nginx Reverse Proxy with HTTPS
$ sudo apt install nginx certbot python3-certbot-nginx -y
# Configure proxy_pass to http://localhost:8080
$ sudo certbot --nginx -d jenkins.yourdomain.com
Nginx forwards HTTPS traffic to Jenkins. Certbot auto-obtains SSL certificates.
Chapter 2: Freestyle Jobs & Build Triggers
📖 Definition: Freestyle jobs are the simplest Jenkins job type with SCM, build triggers, build steps, and post-build actions.
# Build Trigger: Poll SCM every 5 minutes
*/5 * * * *
# Build Step: Execute shell
#!/bin/bash
echo "Building at $(date)"
npm install && npm run build
# Post-build: Archive artifacts
dist/**/*
⚙️ Explanation: Cron syntax: minute hour day month weekday. Poll SCM checks Git for changes. Artifacts saved for download.
📁 CASE PROJECT 2.1: Nightly Build with Email Notification
0 2 * * *
Email: team@company.com, Subject: Build #${BUILD_NUMBER} - ${BUILD_STATUS}
Chapter 3: Pipeline as Code (Declarative Pipeline)
📖 Definition: Jenkinsfile defines pipeline as code — version-controlled, reusable, with parallel stages and conditional logic.
pipeline {
agent any
environment { APP_NAME = 'myapp' }
stages {
stage('Checkout') { steps { checkout scm } }
stage('Build') { steps { sh 'npm install' } }
stage('Test') { steps { sh 'npm test' } }
stage('Deploy') { when { branch 'main' } steps { sh 'deploy.sh' } }
}
post { success { echo 'Pipeline succeeded!' } }
}
📝 Breakdown: agent any = any available runner. environment sets variables. when { branch ‘main’ } restricts deployment to main branch only.
Chapter 4: Git Integration & Webhooks
📁 CASE PROJECT 4.1: GitHub Webhook (Real-time Builds)
# Jenkins: Pipeline → Build Triggers → "GitHub hook trigger"
# GitHub: Settings → Webhooks → Add webhook
Payload URL: http://jenkins.yourdomain.com/github-webhook/
Content type: application/json, Events: Just the push event
Webhook sends HTTP POST on every push → Jenkins builds immediately. No polling needed.
Chapter 5: Build Automation & Testing
📁 CASE PROJECT 5.1: Multi-Branch Pipeline
stage('Deploy to Dev') { when { branch 'feature/*' } steps { sh 'deploy-dev.sh' } }
stage('Deploy to Prod') { when { branch 'main' } steps { input message: 'Deploy to production?' } }
Multibranch Pipeline auto-discovers branches. input step adds manual approval gate for production.
Chapter 6: Docker Integration with Jenkins
📁 CASE PROJECT 6.1: Build & Push to Docker Hub
stage('Docker Build') {
steps {
script {
docker.build("myapp:${env.BUILD_NUMBER}")
docker.withRegistry('https://registry.hub.docker.com', 'docker-cred') {
docker.image("myapp:${env.BUILD_NUMBER}").push()
docker.image("myapp:${env.BUILD_NUMBER}").push('latest')
}
}
}
}
Builds Docker image with build number tag. Pushes to Docker Hub. ‘latest’ tag also updated.
Chapter 7: AWS EC2 Deployment Pipeline
📖 Project: Deploy Docker container to AWS EC2 with custom domain. Complete production-grade pipeline.
GitHub → Jenkins → Docker Build → Push Registry → SSH to EC2 → Run Container → Custom Domain
# Pre-requisites on AWS EC2:
$ sudo apt update && sudo apt install docker.io -y
$ sudo usermod -aG docker ubuntu
# Security Group: Open ports 22, 80, 443, 8080
# Jenkins Pipeline Stage:
stage('Deploy to AWS EC2') {
steps {
sshagent(['aws-ec2-key']) {
sh """
ssh -o StrictHostKeyChecking=no ubuntu@myapp.yourdomain.com '
docker pull myapp:${BUILD_NUMBER} &&
docker stop myapp || true &&
docker rm myapp || true &&
docker run -d --name myapp -p 80:3000 myapp:${BUILD_NUMBER}
'
"""
}
}
}
🚀 Explanation: SSH into EC2 using stored credentials. Pull latest image. Stop/remove old container. Run new container on port 80. Custom domain points to EC2 IP.
Custom Domain Setup (Dummy Domain Example)
# /etc/hosts (local testing) or DNS A record:
your-ec2-ip myapp.yourcompany.com
# Verify: curl http://myapp.yourcompany.com
Chapter 8: End-to-End CI/CD Project — Complete Walkthrough
🎯 Final Project: From zero to production: Developer writes code → GitHub → Jenkins → Docker → AWS EC2 → Custom Domain. Real company workflow.
📁 COMPLETE PIPELINE: Sample Node.js App
Step 1: Sample Application (app.js)
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('CI/CD with Jenkins! 🚀'));
app.get('/health', (req, res) => res.status(200).send('OK'));
app.listen(3000);
Step 2: Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Step 3: Complete Jenkinsfile
pipeline {
agent any
environment {
DOCKER_IMAGE = 'myapp'
DOCKER_TAG = "${env.BUILD_NUMBER}"
EC2_HOST = 'ubuntu@myapp.yourcompany.com'
}
stages {
stage('Checkout') { steps { checkout scm } }
stage('Install') { steps { sh 'npm install' } }
stage('Test') { steps { sh 'npm test' } }
stage('Docker Build') {
steps { script { docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}") } }
}
stage('Push to Registry') {
steps {
script {
docker.withRegistry('', 'docker-cred') {
docker.image("${DOCKER_IMAGE}:${DOCKER_TAG}").push()
docker.image("${DOCKER_IMAGE}:${DOCKER_TAG}").push('latest')
}
}
}
}
stage('Deploy to AWS EC2') {
steps {
sshagent(['aws-ec2-key']) {
sh """
ssh -o StrictHostKeyChecking=no ${EC2_HOST} '
docker pull ${DOCKER_IMAGE}:${DOCKER_TAG} &&
docker stop myapp || true &&
docker rm myapp || true &&
docker run -d --name myapp -p 80:3000 ${DOCKER_IMAGE}:${DOCKER_TAG}
'
"""
}
}
}
stage('Verify') {
steps { sh "curl -sSf http://myapp.yourcompany.com || exit 1" }
}
}
post { success { echo '✅ Deployment successful!' } }
}
Step 4: GitHub Webhook Configuration
GitHub Repo → Settings → Webhooks → Add webhook
Payload URL: http://jenkins.yourcompany.com/github-webhook/
Content type: application/json | Events: Push events
Step 5: Run the Pipeline
$ git add . && git commit -m "CI/CD pipeline ready" && git push origin main
# Jenkins automatically triggers the pipeline
# After success, visit: http://myapp.yourcompany.com
🎉 Final Result: Every git push triggers automated build, test, Docker build, push to registry, and deployment to AWS EC2. Your app is live on custom domain with zero manual intervention!
💡 Production Best Practices:
• Store credentials in Jenkins Credentials Store (never hardcode).
• Use Blue Ocean plugin for better visualization.
• Implement health check endpoint and verify after deployment.
• Add rollback stage to revert to previous Docker tag.
• Use environment-specific variables for dev/staging/prod.
• Store credentials in Jenkins Credentials Store (never hardcode).
• Use Blue Ocean plugin for better visualization.
• Implement health check endpoint and verify after deployment.
• Add rollback stage to revert to previous Docker tag.
• Use environment-specific variables for dev/staging/prod.
🌓 Light / Dark Mode