Jenkins
Jenkins is an open-source automation server widely used in enterprise environments for CI/CD pipelines. It uses a Groovy-based Jenkinsfile to define declarative pipelines with stages, agents, and post-build actions — running on self-hosted infrastructure with full customisation.
Understanding Jenkins
What Is Jenkins in Simple Terms
Jenkins is the granddaddy of CI/CD servers. It has been running pipelines since 2011 and is still the dominant CI platform in large enterprise environments — banks, telcos, insurance companies, and any organisation that cannot use cloud-hosted CI for compliance reasons. Many Indian enterprises running on-premise infrastructure use Jenkins as their primary automation server.
The modern way to use Jenkins is through declarative Jenkinsfiles — pipeline configuration stored in the repository alongside the code, not configured through a UI.
How It Works
+------------------------------------------+| Jenkins Controller || Web UI, job scheduling, plugin mgmt || Stores build history, credentials |+------------------------------------------+ | distributes jobs to agents | +---------+---------+ | | | v v v+----------+ +----------+ +----------+| Agent 1 | | Agent 2 | | Agent 3 || Java | | Node.js | | Docker || builds | | builds | | builds |+----------+ +----------+ +----------+ Or: dynamic Kubernetes agents Each build gets a fresh pod Pod terminates after buildDeclarative Jenkinsfile:
// Jenkinsfilepipeline { agent none // no global agent -- defined per stage environment { ECR_REGISTRY = '123456789.dkr.ecr.ap-south-1.amazonaws.com' IMAGE_NAME = 'payment-api' // Bind Jenkins credential to env var AWS_CREDENTIALS = credentials('aws-ecr-credentials') } stages { stage('Build') { agent { docker { image 'docker:24-dind' } } steps { script { docker.build("${ECR_REGISTRY}/${IMAGE_NAME}:${GIT_COMMIT}") docker.withRegistry("https://${ECR_REGISTRY}") { docker.image("${IMAGE_NAME}:${GIT_COMMIT}").push() } } } } stage('Test') { // Run test and lint in parallel parallel { stage('Unit Tests') { agent { docker { image 'node:20-alpine' } } steps { sh 'npm ci' sh 'npm test' junit 'test-results/*.xml' } } stage('Lint') { agent { docker { image 'node:20-alpine' } } steps { sh 'npm ci' sh 'npm run lint' } } } } stage('Deploy Staging') { agent { label 'k8s-deployer' } when { branch 'main' // only on main branch } steps { sh "./deploy.sh staging ${GIT_COMMIT}" } } stage('Deploy Production') { agent { label 'k8s-deployer' } when { branch 'main' } // Pause and wait for human input input { message 'Deploy to production?' ok 'Deploy' submitter 'tech-leads' } steps { sh "./deploy.sh production ${GIT_COMMIT}" } } } post { success { slackSend channel: '#deployments', message: "SUCCESS: ${env.JOB_NAME} #${env.BUILD_NUMBER}" } failure { slackSend channel: '#deployments', color: 'danger', message: "FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}" } always { cleanWs() // clean workspace after every build } }}Practical Commands
## Jenkins CLIjava -jar jenkins-cli.jar -s http://jenkins.internal \ -auth admin:API_TOKEN build payment-api-pipeline ## Trigger build with parametersjava -jar jenkins-cli.jar -s http://jenkins.internal \ build payment-api-pipeline \ -p ENVIRONMENT=staging \ -p VERSION=v1.2.3 ## Get build logjava -jar jenkins-cli.jar -s http://jenkins.internal \ console payment-api-pipeline 42 ## build number 42 ## Restart Jenkins safelyjava -jar jenkins-cli.jar -s http://jenkins.internal safe-restartTroubleshooting
| Symptom | Check | What to Look For |
|---|---|---|
| Build stuck in queue | Agent availability | Agents offline or label mismatch |
| Credentials not found | Manage Jenkins > Credentials | Credential ID matches Jenkinsfile |
| Pipeline syntax error | Replay > edit and retry | Groovy syntax in Jenkinsfile |
| Workspace conflicts | Parallel build settings | Enable concurrent build isolation |
TipUse the Jenkins Pipeline Syntax generator (available at http://jenkins.internal/pipeline-syntax/) to generate correct Groovy syntax for any plugin step. It is an interactive UI that produces snippet code — far faster than reading plugin documentation.
RememberAlways use
agent noneat the pipeline level and declare agents per stage. Using a global agent means all stages run on the same machine sequentially. Per-stage agents allow parallel execution on different machines and Docker containers — which is how modern Jenkins pipelines run efficiently.
SecurityStore all credentials in the Jenkins Credentials Store — never hardcode passwords, API keys, or tokens in the Jenkinsfile. Use
credentials()binding to inject them as environment variables. The Jenkinsfile is committed to Git and visible to anyone with repository access.
Common MistakeUsing scripted pipelines instead of declarative. Scripted pipelines are raw Groovy — powerful but fragile, hard to read, and difficult to validate. Declarative pipeline syntax is structured, validated before execution, and supports the full range of Jenkins features. Always start with declarative unless you have a specific reason that requires scripted.
Frequently Asked Questions
Why do teams still choose self-hosted Jenkins over hosted CI/CD like GitHub Actions or GitLab CI?
Jenkins predates modern hosted CI by over a decade (first released in 2011 as a Hudson fork) and its main draw now is its plugin ecosystem — over 1,800 plugins covering nearly any tool integration, legacy system, or custom build requirement — plus full control over the build infrastructure, which matters for regulated environments that can't send build data to a third-party SaaS. The tradeoff is you own patching, scaling agents, and securing the Jenkins master yourself.
What's a common operational mistake with Jenkins pipelines in production?
Running builds directly on the Jenkins controller node instead of dedicated agents — this couples build workload to the same machine serving the web UI and orchestrating all other jobs, so one runaway build can degrade or crash the whole instance for every team using it. Best practice is agent-based execution (static or dynamic, e.g. Kubernetes pod agents) so the controller only orchestrates, never executes build steps itself.