Jenkins is like that trusty pickup truck in your driveway. It's been around forever, it's not the prettiest thing on the road, but it just works. Day after day. Without complaint.
When Hudson (Jenkins' predecessor) was first released in 2005, it revolutionized how teams built software. Jenkins was forked in 2011 and has been going strong ever since. While newer tools like GitHub Actions, GitLab CI, and CircleCI have their place, Jenkins remains the most flexible, most customizable CI/CD platform you can run yourself.
And here's the thing: it's completely free. No per-minute pricing. No seat limits. Run it on your laptop, on a cheap VPS, or scale it up to hundreds of agents. Your infrastructure, your rules.
Why Jenkins Still Matters
You might be wondering: why bother with Jenkins when GitHub Actions is right there, built into the platform I already use?
Good question. Here's why you might choose Jenkins:
- Full control — You own the infrastructure. No third-party dependency for your CI/CD.
- Infinite customization — If there's a thing you want to automate, Jenkins can probably do it.
- Run anywhere — Linux, Windows, macOS, containers, cloud, on-prem. Doesn't matter.
- Huge plugin ecosystem — Over 1,800 plugins. Need to integrate with something? There's probably a plugin.
- It's free — Completely open source. No vendor lock-in.
- Industry standard — If you work in enterprise, chances are you'll encounter Jenkins.
The trade-off is that Jenkins requires more setup and maintenance than cloud-native solutions. But for that price, you get complete autonomy.
Installing Jenkins
Jenkins runs anywhere, but let's start simple. I'll show you how to run it with Docker — the fastest way to get up and running.
The Quick Docker Way
docker run -d \
--name jenkins \
-p 8080:8080 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
Wait a minute for Jenkins to start, then visit http://localhost:8080. You'll be prompted for an initial admin password — get it with:
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
Enter that password, install the suggested plugins, create your admin user, and boom — you're in.
Installing on a Server
If you want to run Jenkins directly on a Linux server (not in Docker), here's how on Debian/Ubuntu:
# Add Jenkins repository
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
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
# Install Jenkins
sudo apt update
sudo apt install jenkins java-17-openjdk
# Start Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
Jenkins runs on port 8080 by default. Visit http://your-server-ip:8080 to set it up.
Your First Pipeline
Let's build something. We'll create a simple pipeline that checks out code, runs tests, and reports the results.
Creating a Pipeline Job
- Click "New Item" in Jenkins
- Give it a name (like "my-first-pipeline")
- Select "Pipeline" as the type
- Click OK
Now scroll down to the Pipeline section and paste this in:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
echo 'Checking out source code...'
# In a real pipeline, you'd use:
# git 'https://github.com/your/repo.git'
}
}
stage('Build') {
steps {
echo 'Building the project...'
# Example for different languages:
// sh 'npm install'
// sh 'pip install -r requirements.txt'
// sh 'go build'
}
}
stage('Test') {
steps {
echo 'Running tests...'
// sh 'npm test'
// sh 'pytest'
}
}
stage('Deploy') {
steps {
echo 'Deploying...'
// Your deployment commands here
}
}
}
post {
always {
echo 'Pipeline completed!'
}
success {
echo 'Build succeeded!'
}
failure {
echo 'Build failed!'
}
}
}
Click "Save" and then "Build Now". Watch the console output — you'll see each stage execute.
The Jenkinsfile: Pipeline as Code
The above example had the pipeline defined in Jenkins itself. That's fine for learning, but for real projects, you want your pipeline defined in code, committed to your repository. That's what a Jenkinsfile is.
Create a file called Jenkinsfile in your repository root:
pipeline {
agent {
docker {
image 'node:18-alpine'
args '-p 3000:3000'
}
}
environment {
NODE_ENV = 'test'
}
stages {
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'
archiveArtifacts artifacts: 'build/**', fingerprint: true
}
}
}
Now update your Jenkins job to use "Pipeline script from SCM" instead of "Pipeline script". Point it at your repository and branch. Now your pipeline is version-controlled, code-reviewed, and tracks with your code.
agent docker directive to spin up fresh containers for each build. Each build starts clean — no dependency pollution, no "works on my machine" issues.
Distributed Builds with Agents
One Jenkins instance can only do so much. When your builds start piling up, you need agents (formerly called "slaves") — separate machines that do the actual work while your master coordinates.
Setting Up an Agent
On your agent machine (can be another server, your desktop, whatever):
# Install Java
sudo apt install openjdk-17-jre-headless
# Create a dedicated user
sudo useradd -m -s /bin/bash jenkins
# Set up SSH keys for master to connect
sudo -u jenkins ssh-keygen -t rsa -b 4096
Copy the public key to your master:
sudo cat /home/jenkins/.ssh/id_rsa.pub
Add this as a credential in Jenkins (Manage Jenkins → Manage Credentials → Add Credentials → SSH Username with private key).
Now add the agent in Jenkins: Manage Jenkins → Manage Nodes → New Node. Give it a name, select "Permanent Agent", and configure:
- Remote root directory:
/home/jenkins/agent - Labels:
dockerorlinux - Usage: "Use this node as much as possible"
- Launch method: "Launch agents via SSH"
- Host: your agent's IP
- Credentials: the SSH key you just added
Now your builds can run in parallel across multiple machines.
Essential Plugins
Jenkins has thousands of plugins. Here are the ones I install on every Jenkins setup:
- Pipeline — Required for pipeline jobs (usually pre-installed)
- Git — Required for checking out code
- Docker Pipeline — Build and use Docker inside pipelines
- Blue Ocean — Modern UI for Jenkins (highly recommended)
- Credentials Binding — Securely use secrets in pipelines
- Email Extension — Better email notifications
- Slack Notification — Send build results to Slack
- JUnit — Publish test results
- Jenkinsfile Runner — Test Jenkinsfiles locally
Security Best Practices
Jenkins is powerful, but it executes arbitrary code. That's a big attack surface. Here's how to secure it:
1. Enable Security
Go to Manage Jenkins → Security. Enable "Jenkins' own user database" and let users sign up only if you want. Or connect to LDAP/Active Directory for enterprise.
2. Use Matrix Authorization
Configure permissions carefully. Developers need to build and configure jobs, but maybe not manage system settings.
3. Don't Run as Root
Jenkins should run as a dedicated service account, not root. Ever.
4. Secrets Management
Use the Credentials Binding plugin or HashiCorp Vault integration for API keys, passwords, and certificates. Never hardcode secrets in Jenkinsfiles.
5. Limit Script Approval
If you use Groovy scripts in pipelines, review what's allowed in Manage Jenkins → In-process Script Approval.
6. Keep It Updated
Jenkins has a history of security vulnerabilities. Update regularly.
Blue Ocean: The Modern UI
If the classic Jenkins UI makes your eyes bleed, try Blue Ocean. It's a modern, visual interface for Jenkins pipelines.
Install it from the Plugin Manager. Then either use the Blue Ocean link in the sidebar or open /blue on your Jenkins instance.
Blue Ocean shows you:
- Pipeline visualization (the pipeline as a flowchart)
- Branch and pull request builds
- Parallel stage execution
- Detailed logs without page reloads
It makes Jenkins feel like a completely different tool.
Jenkins vs. The World
Let's be honest: Jenkins isn't perfect. The UI can be clunky. Plugin maintenance varies. Configuration can feel verbose.
Here's how it compares to alternatives:
- GitHub Actions — Easier to start, integrated with GitHub. But you're tied to GitHub and their pricing.
- GitLab CI — Excellent integrated CI/CD if you use GitLab. But you need GitLab.
- CircleCI — Good cloud service, but expensive at scale.
- Tekton — Kubernetes-native, if that's your thing. More complex.
Jenkins wins when you need total control, want to run on your own infrastructure, and don't want vendor lock-in.
Automation Ideas with Jenkins
Once you've got Jenkins running, here are things you can automate beyond just "build and test":
- Database migrations — Run automatically before deploys
- Infrastructure provisioning — Spin up/down test environments
- Security scanning — Run SAST/DAST tools as part of your pipeline
- Static site generation — Rebuild your blog when you push markdown
- Scheduled jobs — Nightly builds, weekly reports
- Container image building — Build and push Docker images
- Compliance checking — Verify infrastructure as code policies
Anything you can script can be automated with Jenkins.
Wrapping Up
Jenkins isn't the shiny new tool. It won't make your dev team ooh and ahh in demo reviews. But it will reliably run your automation 24/7, 365 days a year, without asking for more money.
Learn Jenkins. It's a skill that'll serve you in every job you take. And there's something satisfying about having your own CI/CD server, humming along in a corner of your infrastructure, doing the boring work so you don't have to.
Now go build something.
The revolution will not be proprietary.