Jenkins

The old reliable that still gets the job done

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:

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.

Important: Jenkins is a Java app and needs some resources. For a basic setup, I recommend at least 2GB RAM and a decent CPU. If you're running build agents too, add more.

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

  1. Click "New Item" in Jenkins
  2. Give it a name (like "my-first-pipeline")
  3. Select "Pipeline" as the type
  4. 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.

Pro tip: Use the 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:

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:

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:

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:

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":

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.

// Comments

Leave a Comment