CI/CD automation from freestyle to declarative and scripted pipelines, user management, shared libraries, agents, and production patterns.
15
Chapters
40+
Pipelines
100%
Free
01βοΈ
Introduction to Jenkins
The Heart of CI/CD
Jenkins is an open-source automation server that builds, tests, and deploys your code automatically. Think of it as a robot that does all the boring repetitive work β every time you push code to Git, Jenkins picks it up, builds it, runs tests, creates a Docker image, and deploys it. No human intervention needed.
Jenkins Architecture β Simple Explanation
π₯οΈ
Controller (Master)
The brain of Jenkins. It schedules jobs, stores configuration, serves the web dashboard. Think of it as the manager who assigns work but does NOT do the work himself.
π§
Agent (Worker)
The hands that actually do the building. These are separate machines (VMs, containers, K8s pods) that run your builds. The controller tells the agent: "build this project" and the agent does it.
π
Job / Pipeline
A set of instructions: "pull code from Git, run Maven build, run tests, push Docker image". Like a recipe that Jenkins follows step by step.
π
Build / Run
One execution of a job. Build #45 means the job ran for the 45th time. Each build has logs, status (success/fail), and artifacts.
π‘ Golden Rule
In production, the Jenkins controller should NEVER build anything itself. All builds run on agents. The controller only manages and serves the dashboard. This is the most asked interview question about Jenkins architecture.
02π₯
Installation & Setup
Get Jenkins Running in 5 Minutes
The fastest way to try Jenkins is Docker. For production, install on a dedicated Linux server or run on Kubernetes.
Docker Installation (Quickest)
TERMINAL# Run Jenkins with Docker β ready in 30 seconds
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts-jdk17
# Get the initial admin password
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# Output: a1b2c3d4e5f6... (copy this)
βPaste the initial admin password from the command above
βChoose "Install Suggested Plugins" (installs the essential plugins)
βCreate your first admin user (NEVER use the built-in admin in production)
βSet the Jenkins URL (e.g., https://jenkins.yourcompany.com)
βInstall additional plugins: Blue Ocean, Docker Pipeline, Kubernetes
βSet up your first build agent (never run builds on the controller)
03π±οΈ
Freestyle Jobs (Classic Editor)
Point-and-Click Builds β No Code Needed
Freestyle jobs are configured entirely through the Jenkins web UI. You click buttons and fill forms instead of writing code. They are great for learning Jenkins, but for production use Pipelines (code-based). Think of Freestyle as training wheels.
Creating a Freestyle Job β Step by Step
βDashboard β New Item β Enter name "build-my-app" β Select "Freestyle project" β OK
βSource Code Management β Select "Git" β Paste your Git repo URL β Add credentials if private repo
βBuild Triggers β Check "GitHub hook trigger for GITScm polling" (auto-build on every push) OR check "Poll SCM" and enter H/5 * * * * (check every 5 minutes)
Every Freestyle job is a ticking time bomb. If Jenkins crashes and you don't have backups, all your Freestyle configs are gone. Pipelines live in Git β they survive anything. Migrate to Pipelines as soon as you learn the basics.
04π
Declarative Pipeline
The Modern Way β Pipeline as Code
Declarative Pipeline is the recommended way to write Jenkins pipelines. It uses a clean, structured syntax that is easy to read even if you don't know Groovy. The pipeline lives in a file called "Jenkinsfile" in your Git repository β right next to your application code.
Complete Declarative Pipeline β Explained Line by Line
JENKINSFILEpipeline { // Everything inside this block
agent any // Run on any available agent
environment { // Variables available to all stages
APP_NAME = 'order-service'
REGISTRY = 'registry.company.com'
VERSION = "${env.BUILD_NUMBER}" // Jenkins build number
}
options {
timeout(time: 30, unit: 'MINUTES') // Kill build if takes >30 min
disableConcurrentBuilds() // Only 1 build at a time
buildDiscarder(logRotator(numToKeepStr: '10')) // Keep last 10 builds
}
triggers {
pollSCM('H/5 * * * *') // Check Git every 5 minutes
}
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'https://github.com/org/order-service.git',
credentialsId: 'github-token'
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml' // Publish test results
}
}
}
stage('Docker Build & Push') {
steps {
sh "docker build -t ${REGISTRY}/${APP_NAME}:${VERSION} ."
sh "docker push ${REGISTRY}/${APP_NAME}:${VERSION}"
}
}
stage('Deploy to Staging') {
when { branch 'develop' } // Only on develop branch
steps {
sh "kubectl set image deploy/${APP_NAME} app=${REGISTRY}/${APP_NAME}:${VERSION} -n staging"
}
}
stage('Approval') {
when { branch 'main' }
steps {
input message: 'Deploy to Production?',
ok: 'Yes, Deploy!',
submitter: 'admin,lead-devops' // Only these users can approve
}
}
stage('Deploy to Production') {
when { branch 'main' }
steps {
sh "kubectl set image deploy/${APP_NAME} app=${REGISTRY}/${APP_NAME}:${VERSION} -n production"
}
}
}
post { // Runs AFTER all stages
success {
slackSend channel: '#deploys', color: 'good',
message: "SUCCESS: ${JOB_NAME} #${BUILD_NUMBER}"
}
failure {
slackSend channel: '#deploys', color: 'danger',
message: "FAILED: ${JOB_NAME} #${BUILD_NUMBER}"
}
always {
cleanWs() // Clean workspace after build
}
}
}
Key Directives Explained
Directive
What It Does
Simple Explanation
agent
Where to run
Pick a machine to run on. agent any = any available, agent { docker { image \"node:20\" } } = inside a container
environment
Set variables
Like setting constants. Available in all stages. Can use credentials() to inject secrets
stages
Group of stages
The steps of your recipe: Build β Test β Deploy. They run in order, top to bottom
when
Conditional stage
Only run this stage IF condition is true. when { branch \"main\" } = only on main branch
input
Human approval
Pauses the pipeline and waits for someone to click Approve. Used before production deploys
post
After-pipeline
Runs after everything. success{} for green builds, failure{} for red, always{} for both
options
Pipeline settings
timeout, retry, build discard policy. Safety nets for your pipeline
triggers
Auto-run
pollSCM checks Git for changes. cron runs on a schedule. upstream triggers after another job
05π
Advanced Declarative Features
Parallel, Matrix, Retry & More
Real pipelines need parallel execution, conditional logic, retries, and matrix builds. These advanced features make your pipelines production-ready.
Parallel Stages β Run Multiple Things at Once
JENKINSFILEstage('Quality Gates') {
parallel { // All 3 run at the SAME TIME
stage('Unit Tests') {
steps { sh 'mvn test' }
}
stage('Integration Tests') {
steps { sh 'mvn verify -P integration' }
}
stage('Security Scan') {
steps { sh 'trivy image myapp:latest' }
}
}
}
// Without parallel: 5+10+3 = 18 minutes
// With parallel: max(5,10,3) = 10 minutes β saved 8 minutes!
Full Groovy Power β When Declarative Isn't Enough
Scripted Pipeline is the older, more flexible way to write Jenkins pipelines. It uses full Groovy programming β variables, loops, try-catch, API calls. Use it when Declarative is too limiting (complex logic, dynamic stages). Think of Declarative as a form you fill out, Scripted as writing your own essay.
Need a for loop to generate stages based on a list
Complex error handling
Need try-catch-finally with custom recovery logic
API calls during pipeline
Need to call REST APIs and use results to decide what to do next
Build matrix from external source
Stages generated from a JSON file or API response
Legacy pipelines
Old pipelines written before Declarative existed
Full Scripted Pipeline Example
SCRIPTED PIPELINEnode('docker-agent') {
def services = ['user-service', 'order-service', 'payment-service']
def registry = 'registry.company.com'
stage('Checkout') {
checkout scm
}
stage('Build All Services') {
for (svc in services) {
dir(svc) { // Enter subdirectory
sh 'mvn clean package -DskipTests'
}
}
}
stage('Test All Services') {
def parallelTests = [:]
for (svc in services) {
def serviceName = svc // Must capture in local var for closure
parallelTests[serviceName] = {
dir(serviceName) {
sh 'mvn test'
}
}
}
parallel parallelTests // Run all tests in parallel!
}
stage('Docker Build & Push') {
for (svc in services) {
dir(svc) {
sh "docker build -t ${registry}/${svc}:${env.BUILD_NUMBER} ."
sh "docker push ${registry}/${svc}:${env.BUILD_NUMBER}"
}
}
}
stage('Deploy') {
try {
sh 'kubectl apply -f k8s/'
sh 'kubectl rollout status deployment/order-service --timeout=120s'
} catch (err) {
echo "Deploy failed: ${err.message}"
sh 'kubectl rollout undo deployment/order-service'
error 'Deployment failed and was rolled back'
}
}
}
π‘ Interview Answer
\"Declarative is structured and easier to read β use it for 90% of pipelines. Scripted gives full Groovy β use it for complex logic like dynamic stages, API-driven builds, or custom error handling. Most companies standardize on Declarative.\"
07π
Real-World Jenkinsfiles
Complete Pipeline Examples for Every Stack
Copy-paste ready Jenkinsfile examples for the most common technology stacks. Each one is production-tested.
Jenkins Credentials Manager stores passwords, tokens, SSH keys, and certificates encrypted. They are injected into builds at runtime β your Jenkinsfile never contains actual secrets.
Credential Types
Type
Use Case
How to Access in Pipeline
Username + Password
Git repos, Docker Hub, Nexus
credentials(\"cred-id\") β sets CRED_USR and CRED_PSW variables
Secret Text
API tokens, webhook URLs, Slack tokens
credentials(\"token-id\") β single string variable
Jenkins automatically masks credentials in build logs. But be careful with echo, printenv, or debugging that might accidentally expose secrets. Never use sh \"echo $PASSWORD\" in production.
09π§
Agents & Distributed Builds
Scale Jenkins Across Machines
Agents are separate machines that execute your builds. Without agents, Jenkins controller does everything β which is slow, insecure, and a single point of failure. With agents, you can run 50 builds in parallel across different machines.
Agent Types β Simple Comparison
π₯οΈ
Permanent Agent
A VM or server permanently connected to Jenkins. Always running, always ready. Good for specialized builds (GPU, big disk). Downside: you pay for it even when idle.
π³
Docker Agent
Jenkins spins up a Docker container for each build and destroys it after. Every build gets a clean environment. Most popular choice for most teams.
βΈοΈ
Kubernetes Agent
Jenkins creates a K8s pod for each build. Auto-scales: busy = more pods, idle = fewer pods. Best for large teams on Kubernetes.
βοΈ
Cloud Agent (EC2/Azure)
Jenkins launches a cloud VM for each build. Shuts down when done. Pay only for build time. Good for burst capacity.
In a real company, not everyone should be able to delete pipelines or deploy to production. Jenkins has a complete permission system β you create users, organize them into roles, and control exactly what each role can do.
Setting Up Users
βGo to Manage Jenkins β Security β Authentication
βChoose "Jenkins own user database" (simplest) or LDAP/Active Directory (enterprise)
βCheck "Allow users to sign up" only if you want self-registration
βCreate users manually: Manage Jenkins β Users β Create User
βFor SSO: install "SAML Plugin" or "OpenID Connect Plugin" to integrate with Okta/Azure AD
Role-Based Access Control (RBAC)
RBAC SETUP# Install plugin: Role-based Authorization Strategy
# Manage Jenkins β Security β Authorization β Role-Based Strategy
# Step 1: Create Global Roles
# admin β Full access to everything
# developer β Read + build jobs (no delete, no configure Jenkins)
# viewer β Read-only (can see logs but can't trigger builds)
# Step 2: Create Project Roles (Pattern-based)
# team-a-dev β Pattern: team-a-.* β Build + Read
# team-b-dev β Pattern: team-b-.* β Build + Read
# This means team-a can only see and build team-a jobs!
# Step 3: Assign Users to Roles
# suresh β admin (global) + team-platform-dev (project)
# priya β developer (global) + team-a-dev (project)
# intern β viewer (global)
Folder-Level Permissions
π
Jenkins Folders
Organize jobs into folders: /team-a/build-app, /team-b/deploy-api. Each folder can have its own permissions.
π
Folder Credentials
Store credentials at folder level. Team-A's AWS keys are only available to Team-A's jobs. Team-B can't see them.
π€
Folder RBAC
Assign roles per folder. Suresh is admin of /platform/ folder but only viewer of /frontend/ folder.
Best Practices for User Management
βNever share the built-in admin account β create individual users
βUse LDAP/Active Directory or SSO (Okta/Azure AD) for enterprise
βInstall Role-Based Authorization Strategy plugin on day one
βCreate roles like admin, developer, deployer, viewer β not per-person permissions
βUse folder-level permissions so teams can't access each other's secrets
βRestrict who can approve production deployments (use submitter in input step)
βEnable audit trail logging β know who did what and when
βDisable "Remember me" for security-sensitive environments
11π
Shared Libraries
Write Once, Use in All Pipelines
When you have 50 microservices with almost identical pipelines, you don't copy-paste the same Jenkinsfile 50 times. You create a Shared Library β a central Git repo with reusable pipeline functions. Change it once, all 50 pipelines get the update.
Library Structure
DIRECTORYjenkins-shared-library/ (a Git repository)
vars/
buildDockerImage.groovy // Global function β called like: buildDockerImage()
deployToK8s.groovy // Global function β called like: deployToK8s()
notifySlack.groovy // Global function
standardPipeline.groovy // Full pipeline template
src/
com/company/Utils.groovy // Helper classes
resources/
templates/ // Config file templates
50 microservices Γ same Docker+K8s pipeline = maintain 1 shared library instead of 50 Jenkinsfiles. Fix a bug in the deploy step? Change 1 file, all 50 services get the fix automatically. This is how Netflix, Amazon, and Reliance scale CI/CD.
12π
Essential Plugins β Detailed
Must-Have Plugins with Setup Guide
Jenkins without plugins is just a cron scheduler. Plugins make Jenkins powerful. Here are the must-have plugins with what they do and why you need them.
Plugin
What It Does
Why You Need It
Pipeline
Enables Declarative & Scripted pipelines
Without this, no Jenkinsfile support at all. Core plugin.
Git
Clone and checkout Git repositories
Basic Git integration. Installed by default.
Docker Pipeline
Use Docker containers as build agents
Run builds inside containers for clean, reproducible environments.
Kubernetes
Create K8s pods as dynamic build agents
Auto-scale build agents in Kubernetes clusters.
Blue Ocean
Modern visual pipeline UI
Beautiful pipeline visualization. Much better than classic UI.
Credentials Binding
Inject secrets into builds securely
withCredentials() block. Essential for any real pipeline.
Role-Based Authorization
RBAC for Jenkins
Control who can see/build/configure what. Must-have for teams.
SonarQube Scanner
Static code analysis
Quality gates in CI. Block merges with code smells.
Slack Notification
Send Slack messages from pipelines
Build success/failure alerts to team channels.
JaCoCo
Code coverage reports
Track test coverage percentage. Fail builds below threshold.
Job DSL
Create jobs programmatically
Define Jenkins jobs as code. Reproducible Jenkins setup.
Configuration as Code (JCasC)
Entire Jenkins config in YAML
Recreate Jenkins from scratch in minutes. Store config in Git.
Multibranch Pipeline
Auto-create pipelines per branch
Push a branch with Jenkinsfile β pipeline auto-created. Delete branch β pipeline auto-deleted.
Pipeline: Stage View
Visualize pipeline stages
See which stage failed, how long each took.
Timestamper
Add timestamps to build logs
Know exactly when each line was logged. Essential for debugging.
13π§
Jenkins Administration
Backup, Monitoring & JCasC
Running Jenkins in production means keeping it healthy β backups, monitoring, upgrades, and configuration management.
βAdd timeout and retry to network-dependent stages
βNotify on failure only β nobody reads success notifications
βUse Multibranch Pipeline to auto-create/delete branch pipelines
Security Best Practices
βNever hardcode credentials in Jenkinsfile β use Credentials Manager
βEnable RBAC with Role-Based Authorization Strategy plugin
βUse folder-level credentials β team-A can't see team-B's secrets
βPut Jenkins behind a reverse proxy with HTTPS (Nginx or ALB)
βDisable Jenkins CLI β it's a security risk. Use HTTPS API only
βUpdate Jenkins and plugins monthly for security patches
βUse JCasC to define security config in code (auditable, version-controlled)
βRestrict Script Security approvals β review every sandbox escape
βEnable Audit Trail plugin for compliance logging
15πΌ
Interview Questions
30+ Jenkins Q&A for DevOps Interviews
These questions are asked in real DevOps interviews β from entry-level to senior positions.
Architecture & Basics
β
What is Jenkins?
Open-source automation server for CI/CD. Builds, tests, and deploys code automatically. Written in Java. 1800+ plugins.
β
Controller vs Agent?
Controller (master) orchestrates β schedules jobs, stores config, serves UI. Agent (slave) executes builds on separate machines. Controller should NEVER run builds in production.
β
What is a Jenkinsfile?
A text file in your Git repo that defines the CI/CD pipeline as code. Stored alongside application code. Enables Pipeline-as-Code β version-controlled, reviewable.
β
Declarative vs Scripted Pipeline?
Declarative: structured pipeline{} syntax, easier to read, opinionated, recommended for 90% of cases. Scripted: node{} syntax, full Groovy programming, use when Declarative can't handle complex logic.
Pipelines & Features
β
What is a Multibranch Pipeline?
Auto-creates pipeline for every branch that has a Jenkinsfile. Push new branch β pipeline auto-created. Delete branch β pipeline auto-deleted. Industry standard.
β
How to run stages in parallel?
Use parallel { stage(\"A\"){...} stage(\"B\"){...} } inside a parent stage. Reduces pipeline time by running independent tasks simultaneously.
β
What is the when directive?
Conditional execution. when { branch \"main\" } runs only on main. when { not { changeRequest() } } skips for PRs. Controls which stages run based on branch, tag, or expression.
β
What is the input step?
Pauses the pipeline for manual approval. submitter restricts who can approve. Used before production deployments. Pipeline waits until someone clicks Approve.
Security & Administration
β
How to manage secrets?
Jenkins Credentials Manager stores them encrypted. Access via credentials() in environment block or withCredentials() wrapper. Types: username+password, secret text, secret file, SSH key.
β
What is Shared Library?
Central Git repo with reusable pipeline code (vars/ directory). Called with @Library annotation. One library serves 50+ pipelines. Change once, all pipelines get the update.
β
Jenkins RBAC?
Install Role-Based Authorization Strategy plugin. Create roles (admin, developer, viewer). Assign users to roles. Use folder-level permissions for team isolation.
β
What is JCasC?
Jenkins Configuration as Code. Define entire Jenkins setup in YAML β users, credentials, plugins, tools. Store in Git. Recreate Jenkins from scratch in minutes.
Advanced & Comparison
β
Jenkins vs GitHub Actions?
Jenkins: self-hosted, full control, 1800+ plugins, complex. GitHub Actions: cloud-hosted, simpler YAML, tight GitHub integration, pay-per-minute. Jenkins for enterprise control, GH Actions for simplicity.
Machines that execute builds. Types: permanent (VM always connected), Docker (container per build), Kubernetes (pod per build), Cloud (EC2/Azure VM on demand).
β
How to back up Jenkins?
Backup $JENKINS_HOME directory (configs, credentials, job history). Use ThinBackup plugin for scheduling. Store in S3/Azure. With JCasC, rebuild from YAML + Git.
β
What is Blue Ocean?
Modern UI plugin for Jenkins. Visual pipeline editor, beautiful run visualization, GitHub/Bitbucket integration. Makes Jenkins look modern.