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 |
PLACEMENT PRO TIP**Tip:** Use 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.
REMEMBER THIS**Remember:** Always use `agent none` at 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.
COMMON MISTAKE / WARNING**Security:** Store 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 MISTAKE / WARNING**Common Mistake:** Using 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.