Jenkins
Jenkins is the oldest widely-used CI/CD server — open-source, self-hosted, and infinitely extensible through plugins. It remains common in enterprises with strict on-premises requirements.
Jenkins vs GitHub Actions
| Aspect | Jenkins | GitHub Actions |
|---|---|---|
| Hosting | Self-hosted | Cloud (GitHub) |
| Configuration | Jenkinsfile + UI | YAML in repo |
| Plugins | 1800+ plugins | GitHub Marketplace actions |
| Setup complexity | Higher | Lower |
| Cost | Infrastructure + maintenance | Free tier + minutes |
Choose Jenkins when you need on-premises control, custom agents, or complex enterprise integrations.
Installation
Docker (Quickest)
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts-jdk17
Get initial admin password:
docker exec jenkins cat /var/lib/jenkins/secrets/initialAdminPassword
Open http://localhost:8080, install suggested plugins, create admin user.
Linux (Package)
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
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
sudo systemctl enable jenkins
sudo systemctl start jenkins
Declarative Pipeline (Jenkinsfile)
Store pipeline as code in your repository:
// Jenkinsfile
pipeline {
agent any
tools {
nodejs 'NodeJS-20'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
}
post {
always {
junit 'test-results/*.xml'
cleanWs()
}
failure {
mail to: '[email protected]',
subject: "Build Failed: ${env.JOB_NAME}",
body: "Check ${env.BUILD_URL}"
}
}
}
Create a Pipeline job in Jenkins pointing to your Git repo — Jenkins reads Jenkinsfile automatically.
Multibranch Pipeline
Automatically discovers branches and PRs:
- New Item → Multibranch Pipeline
- Add Git source (GitHub, GitLab, Bitbucket)
- Build configuration: by Jenkinsfile
- Scan triggers: webhook or periodic
Each branch gets its own pipeline run on push.
Agents (Nodes)
Run builds on specific machines:
pipeline {
agent {
label 'docker-agent'
}
stages {
stage('Build') {
steps {
sh 'docker build -t myapp .'
}
}
}
}
Configure agents in Manage Jenkins → Nodes. Use Docker agents for isolated builds:
pipeline {
agent {
docker {
image 'node:20-alpine'
}
}
stages {
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
Essential Plugins
| Plugin | Purpose |
|---|---|
| Git | Git SCM integration |
| GitHub Branch Source | Multibranch + webhooks |
| Pipeline | Jenkinsfile support |
| Docker Pipeline | Docker agents and builds |
| JUnit | Test result reporting |
| Blue Ocean | Modern pipeline UI |
| Credentials Binding | Inject secrets into builds |
| SonarQube Scanner | Code quality analysis |
Install via Manage Jenkins → Plugins.
Credentials and Secrets
Store secrets in Jenkins credential store:
- Manage Jenkins → Credentials → Add
- Types: Secret text, Username/password, SSH key
- Reference in pipeline:
environment {
DATABASE_URL = credentials('database-url')
DOCKER_TOKEN = credentials('docker-hub-token')
}
steps {
sh 'echo $DATABASE_URL' // masked in logs
}
Never hardcode secrets in Jenkinsfile — use credentials binding.
Webhook Integration
Trigger builds on Git push:
- Jenkins job → Build Triggers → GitHub hook trigger
- GitHub repo → Settings → Webhooks → Add
- URL:
https://jenkins.example.com/github-webhook/ - Events: push, pull_request
- URL:
Parallel Stages
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
}
stage('Integration Tests') {
steps {
sh 'npm run test:integration'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
}
}
Shared Libraries
Reuse pipeline code across projects:
@Library('my-shared-library') _
pipeline {
agent any
stages {
stage('Deploy') {
steps {
deployToEnv('staging')
}
}
}
}
Backup and Maintenance
- Backup
$JENKINS_HOME(jobs, configs, plugins) - Keep Jenkins LTS updated — test in staging first
- Monitor disk space — build artifacts accumulate
- Use Configuration as Code (JCasC) plugin for reproducible setup
What Comes Next
Apply pipeline design patterns in CI/CD Best Practices — whether using Jenkins, GitHub Actions, or both in hybrid setups.