Command Palette

Search for a command to run...

GitHubGitHub

Jenkins Installation Guide

Install Jenkins 2.580 LTS on Linux, Windows, macOS, Docker and Kubernetes, configure it with Configuration as Code, add agents and build your first pipeline.

Jenkins is a self-hosted automation server. This guide installs the current Jenkins LTS line, configures it with Configuration as Code, adds build agents and runs a first pipeline.

System Requirements

ComponentMinimumRecommended
RAM256 MB4 GB or more for a small team
Disk1 GB50 GB or more
Java2121 (the LTS release with the longest support)
OSAny Linux with systemd, Windows, macOSUbuntu 24.04 / Rocky 9

Installation Instructions

Ubuntu / Debian (apt)

# 1. Install Java 21 first
sudo apt update
sudo apt install -y fontconfig openjdk-21-jre
java -version
 
# 2. Add the signing key
sudo mkdir -p -m 755 /etc/apt/keyrings
sudo wget -O /etc/apt/keyrings/jenkins-keyring.asc \
  https://pkg.jenkins.io/debian-stable/jenkins.io-2026.key
 
# 3. Add the LTS repository
echo "deb [signed-by=/etc/apt/keyrings/jenkins-keyring.asc]" \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
 
# 4. Install Jenkins
sudo apt update
sudo apt install -y jenkins
 
# 5. Start it and enable it at boot
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins

To track the weekly releases instead of the LTS line, use https://pkg.jenkins.io/debian with https://pkg.jenkins.io/debian/jenkins.io-2026.key.

Post-Installation Setup

1. Unlock Jenkins

Open http://localhost:8080 and paste the initial admin password:

# Linux package
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
 
# Docker
docker exec jenkins-controller cat /var/jenkins_home/secrets/initialAdminPassword

2. Configure the Service

Jenkins runs as a systemd service. The package sets the defaults in the unit file:

# Inspect the configuration
sudo systemctl cat jenkins
 
# Change the port, JVM options or JENKINS_HOME
sudo systemctl edit jenkins
[Service]
Environment="JENKINS_PORT=8081"
Environment="JENKINS_HOME=/var/lib/jenkins"
Environment="JAVA_OPTS=-Djenkins.install.runSetupWizard=false -Xmx2g"
# Apply the changes
sudo systemctl daemon-reload
sudo systemctl restart jenkins
 
# Follow the logs
sudo journalctl -u jenkins -f

3. Configure Jenkins as Code

Configuration as Code (JCasC) turns your setup into a version-controlled file instead of clicking through the UI.

# casc.yaml
jenkins:
  systemMessage: "Managed by Configuration as Code"
  numExecutors: 2
  mode: EXCLUSIVE
  securityRealm:
    local:
      allowsSignup: false
      users:
        - id: "admin"
          password: "${JENKINS_ADMIN_PASSWORD}"
  authorizationStrategy:
    globalMatrix:
      permissions:
        - "Overall/Administer:admin"
        - "Overall/Read:authenticated"
  remotingSecurity:
    enabled: true
 
unclassified:
  location:
    url: "https://jenkins.example.com/"
    adminAddress: "devops@example.com"
 
tool:
  git:
    installations:
      - name: "Default"
        home: "git"
 
node:
  builtins:
    - remoteLauncher: "hudson.slaves.SSHLauncher"
      name: "built-in"
      numExecutors: 2
      labelString: "built-in"
# Apply the configuration
sudo systemctl stop jenkins
sudo JENKINS_HOME=/var/lib/jenkins \
  java -jar /usr/share/java/jenkins.war \
  --configuration-as-code=/etc/jenkins/casc.yaml

Build Agents

Jenkins runs jobs on agents. The controller itself has two executors by default; the recommended setup is to set the controller's executors to 0 and run every job on dedicated agents.

# In the Configuration as Code file — the controller only coordinates
jenkins:
  numExecutors: 0

Agents are matched to jobs by labels — for example linux, docker, aarch64 or production.

Agents over SSH

# 1. Create the key pair (on the controller or your workstation)
ssh-keygen -f ~/.ssh/jenkins_agent_key
 
# 2. On the agent host, create the user and install the public key
sudo useradd -m -s /bin/bash jenkins
sudo mkdir -p /home/jenkins/.ssh
cat jenkins_agent_key.pub | sudo tee /home/jenkins/.ssh/authorized_keys
sudo chown -R jenkins:jenkins /home/jenkins/.ssh
sudo chmod 700 /home/jenkins/.ssh
sudo chmod 600 /home/jenkins/.ssh/authorized_keys

In Jenkins: Manage Jenkins → Credentials → Add Credentials with the kind SSH username with private key, then create the node under Manage Jenkins → Nodes → New Node → Permanent Agent and select that credential.

Agents as Docker containers

# Start an agent container that the controller connects to over SSH
docker run -d --rm --name=agent1 -p 22:22 \
  -e "JENKINS_AGENT_SSH_PUBKEY=$(cat ~/.ssh/jenkins_agent_key.pub)" \
  jenkins/ssh-agent:alpine-jdk25

Agents via inbound (JNLP) connection

For agents behind NAT, run the inbound agent container and paste the secret from Manage Jenkins → Nodes → New Node → Inbound agent:

docker run -d --rm --name=agent1 \
  -e "JENKINS_URL=http://controller:8080" \
  -e "JENKINS_SECRET=<AGENT_SECRET>" \
  jenkins/inbound-agent:latest

Kubernetes Agents

The Kubernetes plugin creates a pod per build and removes it afterwards:

# Configure a Kubernetes cloud under Manage Jenkins -> Clouds
// Jenkinsfile
pipeline {
  agent {
    kubernetes {
      yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
            - name: builder
              image: maven:3.9-eclipse-temurin-21
          restartPolicy: Never
      '''
      label "k8s-agent"
    }
  }
  stages {
    stage('Build') {
      steps {
        sh 'mvn -B verify'
      }
    }
  }
}

Your First Pipeline

Create a Jenkinsfile in your repository:

pipeline {
    agent any
 
    options {
        timeout(time: 30, unit: 'MINUTES')
        buildDiscarder(logRotator(numToKeepStr: '20'))
        disableConcurrentBuilds()
    }
 
    environment {
        NODE_ENV = 'test'
    }
 
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
 
        stage('Install dependencies') {
            steps {
                sh 'npm ci'
            }
        }
 
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }
 
    post {
        always {
            echo 'Build finished'
        }
        failure {
            echo 'Build failed'
        }
    }
}

Create the job with Pipeline → Pipeline script from SCM, point it at your repository and the Jenkinsfile.

Useful Plugins

PluginWhat it does
Configuration as CodeManage the controller from a YAML file in Git
PipelineDeclarative and scripted pipelines (built in)
CredentialsStore tokens, passwords and SSH keys
KubernetesDynamic agents on a Kubernetes cluster
GitHub Branch SourceTrigger pipelines from pull requests
Warnings Next GenerationCollect compiler and linter warnings
SonarQubeRun code quality analysis in the pipeline
PrometheusExport build metrics

Upgrading

# 1. Back up JENKINS_HOME before every upgrade
sudo systemctl stop jenkins
sudo tar -czf /var/backups/jenkins-$(date +%F).tar.gz -C /var/lib/jenkins .
sudo systemctl start jenkins
 
# 2. Upgrade the package
sudo apt update && sudo apt install -y --only-upgrade jenkins
 
# 3. Restart and watch the log
sudo systemctl restart jenkins
sudo journalctl -u jenkins -f

Troubleshooting

Security Best Practices

  1. Never run jobs as root — create a dedicated user and use the matrix authorization strategy so nobody is a full administrator.
  2. Enable agent-to-controller security so agents cannot open a reverse channel to the controller (Manage Jenkins → Security).
  3. Keep CSRF protection enabled and use the CSRF proxy setting when the UI is behind a reverse proxy.
  4. Store secrets in the Credentials store, never in a Jenkinsfile or a shell command.
  5. Serve Jenkins over HTTPS — terminate TLS at the reverse proxy.
  6. Restrict who can trigger pipelines and require approval for deployments to production jobs.
  7. Keep the controller and plugins up to date, and subscribe to the Jenkins security advisories.
  8. Back up JENKINS_HOME on a schedule and test the restore.

Next Steps