← Home
βš™οΈ Complete CI/CD Reference

Jenkins Complete Guide

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)
Linux Installation
TERMINAL# Ubuntu/Debian sudo apt update sudo apt install fontconfig openjdk-17-jre curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list sudo apt update && sudo apt install jenkins sudo systemctl start jenkins && sudo systemctl enable jenkins # Get initial admin password sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Post-Install Setup Wizard
βœ“Open http://your-server-ip:8080 in browser
βœ“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)
βœ“Build Environment β†’ Check "Delete workspace before build starts" (clean builds)
βœ“Build Steps β†’ Click "Add build step" β†’ "Execute shell" β†’ Enter your build commands
βœ“Post-build Actions β†’ "Archive artifacts" for JAR/WAR files β†’ "Publish JUnit test results" for test reports
βœ“Click SAVE β†’ Click "Build Now" to test
Example Build Steps
FREESTYLE SHELL# Build Step 1: Execute Shell β€” Spring Boot mvn clean package -DskipTests=false # Build Step 2: Execute Shell β€” Docker docker build -t myapp:${BUILD_NUMBER} . docker push registry.company.com/myapp:${BUILD_NUMBER} # Jenkins Environment Variables (available in all builds): # ${BUILD_NUMBER} β†’ 45 (incrementing build number) # ${JOB_NAME} β†’ build-my-app # ${WORKSPACE} β†’ /var/jenkins_home/workspace/build-my-app # ${GIT_COMMIT} β†’ abc123def456 (Git commit hash) # ${GIT_BRANCH} β†’ origin/main
Freestyle JobsPipeline (Code)
Configured via web UI clicksWritten as code in Jenkinsfile
Stored in Jenkins (not Git)Stored in Git alongside your app
Cannot be code-reviewedCan be reviewed in pull requests
Hard to replicateFully reproducible
No version historyFull Git version history
Limited logic (no loops, conditions)Full programming with Groovy
OK for learning/simple tasksRequired for production
⚠️ Freestyle = Technical Debt

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
DirectiveWhat It DoesSimple Explanation
agentWhere to runPick a machine to run on. agent any = any available, agent { docker { image \"node:20\" } } = inside a container
environmentSet variablesLike setting constants. Available in all stages. Can use credentials() to inject secrets
stagesGroup of stagesThe steps of your recipe: Build β†’ Test β†’ Deploy. They run in order, top to bottom
whenConditional stageOnly run this stage IF condition is true. when { branch \"main\" } = only on main branch
inputHuman approvalPauses the pipeline and waits for someone to click Approve. Used before production deploys
postAfter-pipelineRuns after everything. success{} for green builds, failure{} for red, always{} for both
optionsPipeline settingstimeout, retry, build discard policy. Safety nets for your pipeline
triggersAuto-runpollSCM 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!
Retry β€” Handle Flaky Steps
JENKINSFILEstage('Deploy') { steps { retry(3) { // Try up to 3 times sh 'kubectl apply -f k8s/' } } } stage('Health Check') { steps { timeout(time: 5, unit: 'MINUTES') { waitUntil { script { def response = httpRequest 'http://app:8080/health' return response.status == 200 } } } } }
Matrix Build β€” Test Across Multiple Versions
JENKINSFILEstage('Test Matrix') { matrix { axes { axis { name 'JAVA_VERSION' values '11', '17', '21' } axis { name 'OS' values 'ubuntu', 'alpine' } } stages { stage('Test') { agent { docker { image "openjdk:${JAVA_VERSION}-${OS}" } } steps { sh 'mvn test' } } } } } // Runs 6 combinations: Java11-ubuntu, Java11-alpine, Java17-ubuntu...
06πŸ’»

Scripted Pipeline

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.
Scripted vs Declarative β€” Side by Side
COMPARISON// ═══ DECLARATIVE (Structured, Recommended) ═══ pipeline { agent any stages { stage('Build') { steps { sh 'mvn clean package' } } } } // ═══ SCRIPTED (Flexible, Full Groovy) ═══ node { // 'node' = scripted pipeline keyword stage('Build') { checkout scm sh 'mvn clean package' } }
When to Use Scripted Pipeline
Use CaseWhy Declarative Won't Work
Dynamic number of stagesNeed a for loop to generate stages based on a list
Complex error handlingNeed try-catch-finally with custom recovery logic
API calls during pipelineNeed to call REST APIs and use results to decide what to do next
Build matrix from external sourceStages generated from a JSON file or API response
Legacy pipelinesOld 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.
Spring Boot β†’ Docker β†’ Kubernetes
JENKINSFILEpipeline { agent { label 'docker-agent' } environment { REGISTRY = credentials('ecr-registry-url') IMAGE_NAME = 'order-service' } stages { stage('Build & Test') { steps { sh 'mvn clean package' junit 'target/surefire-reports/*.xml' jacoco execPattern: 'target/jacoco.exec' // Code coverage } } stage('SonarQube') { steps { withSonarQubeEnv('sonar-server') { sh 'mvn sonar:sonar' } waitForQualityGate abortPipeline: true // Fail if quality gate fails } } stage('Docker') { steps { sh "docker build -t ${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} ." sh "docker push ${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}" } } stage('Deploy') { when { branch 'main' } steps { sh "kubectl set image deploy/${IMAGE_NAME} app=${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}" } } } post { failure { slackSend channel: '#deploys', color: 'danger', message: "FAILED: ${JOB_NAME} #${BUILD_NUMBER}" } } }
Node.js + React β†’ S3 + CloudFront
JENKINSFILEpipeline { agent { docker { image 'node:20-alpine' } } stages { stage('Install') { steps { sh 'npm ci' } } stage('Lint') { steps { sh 'npm run lint' } } stage('Test') { steps { sh 'npm test -- --coverage --watchAll=false' } } stage('Build') { steps { sh 'npm run build' } } stage('Deploy') { when { branch 'main' } agent { label 'aws-agent' } // Need AWS CLI steps { withAWS(credentials: 'aws-deploy-creds', region: 'ap-south-1') { sh 'aws s3 sync build/ s3://my-frontend-bucket --delete' sh 'aws cloudfront create-invalidation --distribution-id E12345 --paths "/*"' } } } } }
Python / Django β†’ Docker
JENKINSFILEpipeline { agent { docker { image 'python:3.12-slim' } } stages { stage('Install') { steps { sh 'pip install -r requirements.txt' } } stage('Lint') { steps { sh 'flake8 . --count --max-line-length=120' } } stage('Test') { steps { sh 'python -m pytest tests/ --junitxml=results.xml' } } stage('Docker') { steps { sh 'docker build -t myapp:${BUILD_NUMBER} .' sh 'docker push registry/myapp:${BUILD_NUMBER}' } } } post { always { junit 'results.xml' } } }
08πŸ”

Credentials & Secrets

Never Hardcode Passwords Again

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
TypeUse CaseHow to Access in Pipeline
Username + PasswordGit repos, Docker Hub, Nexuscredentials(\"cred-id\") β†’ sets CRED_USR and CRED_PSW variables
Secret TextAPI tokens, webhook URLs, Slack tokenscredentials(\"token-id\") β†’ single string variable
Secret Filekubeconfig, .env files, certificatescredentials(\"file-id\") β†’ path to temp file
SSH Private KeyGit SSH clone, server accesssshagent([\"ssh-id\"]) { sh \"ssh user@server\" }
CertificateHTTPS certs, mutual TLScredentials(\"cert-id\") β†’ keystore path
Using Credentials β€” Every Pattern You Need
JENKINSFILEpipeline { agent any environment { // Method 1: environment block β€” auto-creates _USR and _PSW DOCKER_CREDS = credentials('docker-hub-login') // DOCKER_CREDS_USR = username // DOCKER_CREDS_PSW = password API_TOKEN = credentials('my-api-token') } stages { stage('Docker Login') { steps { sh 'echo $DOCKER_CREDS_PSW | docker login -u $DOCKER_CREDS_USR --password-stdin' } } stage('Deploy with Kubeconfig') { steps { // Method 2: withCredentials block β€” more control withCredentials([file(credentialsId: 'kubeconfig-prod', variable: 'KUBECONFIG')]) { sh 'kubectl apply -f k8s/deployment.yaml' } } } stage('Git Clone Private Repo') { steps { // Method 3: sshagent for SSH keys sshagent(['github-ssh-key']) { sh 'git clone git@github.com:org/private-repo.git' } } } } }
⚠️ Never Log Secrets

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.
Docker Agent β€” Most Common
JENKINSFILEpipeline { agent { docker { image 'maven:3.9-eclipse-temurin-17' args '-v $HOME/.m2:/root/.m2' // Cache Maven dependencies between builds } } stages { stage('Build') { steps { sh 'mvn clean package' // Runs INSIDE the Maven container } } } }
Kubernetes Pod Agent
JENKINSFILEpipeline { agent { kubernetes { yaml """ apiVersion: v1 kind: Pod spec: containers: - name: maven image: maven:3.9-eclipse-temurin-17 command: ['sleep', 'infinity'] - name: docker image: docker:24-dind securityContext: privileged: true - name: kubectl image: bitnami/kubectl:latest command: ['sleep', 'infinity'] """ } } stages { stage('Build') { steps { container('maven') { sh 'mvn clean package' } } } stage('Docker') { steps { container('docker') { sh 'docker build -t myapp .' } } } stage('Deploy') { steps { container('kubectl') { sh 'kubectl apply -f k8s/' } } } } }
10πŸ‘₯

User Management & RBAC

Control Who Can Do What

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
Creating a Shared Step
GROOVY// vars/buildDockerImage.groovy def call(Map config) { def registry = config.registry ?: 'registry.company.com' def image = config.image def tag = config.tag ?: env.BUILD_NUMBER echo "Building Docker image: ${registry}/${image}:${tag}" sh "docker build -t ${registry}/${image}:${tag} ." sh "docker push ${registry}/${image}:${tag}" return "${registry}/${image}:${tag}" }
Using Shared Library in Jenkinsfile
JENKINSFILE@Library('my-shared-library') _ // Load the library pipeline { agent any stages { stage('Build') { steps { sh 'mvn clean package' } } stage('Docker') { steps { buildDockerImage(image: 'order-service') } } stage('Deploy') { steps { deployToK8s(app: 'order-service', env: 'staging') } } } post { failure { notifySlack(channel: '#deploys', status: 'FAILED') } } }
πŸ’‘ Why This Matters

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.
PluginWhat It DoesWhy You Need It
PipelineEnables Declarative & Scripted pipelinesWithout this, no Jenkinsfile support at all. Core plugin.
GitClone and checkout Git repositoriesBasic Git integration. Installed by default.
Docker PipelineUse Docker containers as build agentsRun builds inside containers for clean, reproducible environments.
KubernetesCreate K8s pods as dynamic build agentsAuto-scale build agents in Kubernetes clusters.
Blue OceanModern visual pipeline UIBeautiful pipeline visualization. Much better than classic UI.
Credentials BindingInject secrets into builds securelywithCredentials() block. Essential for any real pipeline.
Role-Based AuthorizationRBAC for JenkinsControl who can see/build/configure what. Must-have for teams.
SonarQube ScannerStatic code analysisQuality gates in CI. Block merges with code smells.
Slack NotificationSend Slack messages from pipelinesBuild success/failure alerts to team channels.
JaCoCoCode coverage reportsTrack test coverage percentage. Fail builds below threshold.
Job DSLCreate jobs programmaticallyDefine Jenkins jobs as code. Reproducible Jenkins setup.
Configuration as Code (JCasC)Entire Jenkins config in YAMLRecreate Jenkins from scratch in minutes. Store config in Git.
Multibranch PipelineAuto-create pipelines per branchPush a branch with Jenkinsfile β†’ pipeline auto-created. Delete branch β†’ pipeline auto-deleted.
Pipeline: Stage ViewVisualize pipeline stagesSee which stage failed, how long each took.
TimestamperAdd timestamps to build logsKnow 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.
Jenkins Configuration as Code (JCasC)
JCASC YAML# jenkins.yaml β€” Define ENTIRE Jenkins config in one file jenkins: systemMessage: "Jenkins managed by JCasC - do not configure manually" numExecutors: 0 # Controller runs no builds securityRealm: local: allowsSignup: false users: - id: admin password: ${ADMIN_PASSWORD} # From environment variable authorizationStrategy: roleBased: roles: global: - name: admin permissions: ['Overall/Administer'] entries: [{user: admin}] - name: developer permissions: ['Overall/Read', 'Job/Build', 'Job/Read'] entries: [{group: developers}] credentials: system: domainCredentials: - credentials: - string: scope: GLOBAL id: slack-token secret: ${SLACK_TOKEN} unclassified: slackNotifier: teamDomain: mycompany tokenCredentialId: slack-token
Backup Strategy
βœ“Backup $JENKINS_HOME directory regularly (contains all configs, jobs, credentials)
βœ“Use the ThinBackup plugin for scheduled backups
βœ“Store backups in S3 or Azure Blob (not on the same server!)
βœ“Test restore process quarterly β€” a backup you can't restore is useless
βœ“With JCasC, Jenkins can be recreated from scratch using YAML + Git
βœ“Backup Jenkinsfiles are already in Git β€” nothing to do
14πŸ†

Best Practices

Production Jenkins Patterns

Pipeline Best Practices
βœ“Always use Declarative Pipeline over Freestyle (90% of cases)
βœ“Use Scripted Pipeline only when Declarative can't handle the logic
βœ“Store Jenkinsfile in the application Git repo β€” never in Jenkins config
βœ“Use Shared Libraries for common logic across 5+ pipelines
βœ“Run ALL builds on agents β€” never on the controller
βœ“Use Docker agents for clean, reproducible build environments
βœ“Keep pipelines under 15 minutes β€” optimize slow stages
βœ“Fail fast: unit tests first, then integration tests, then deploys
βœ“Use parallel stages for independent tasks (test + lint + scan)
βœ“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.
❓
Jenkins vs Azure DevOps?
Jenkins: CI/CD only, self-hosted, 1800+ plugins. Azure DevOps: full platform (repos, boards, pipelines, artifacts), cloud + on-prem. Azure DevOps for Microsoft/Azure teams.
❓
What are Jenkins agents?
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.
❓
Name 5 essential plugins
Pipeline, Docker Pipeline, Role-Based Auth, Credentials Binding, SonarQube Scanner, Slack Notification, Blue Ocean, Multibranch Pipeline.