cheat-sheets

Jenkins

Jenkins is the long-standing self-hosted automation server. Pipelines are written as a Jenkinsfile in the repository (Groovy based, either declarative or scripted syntax), run on a controller plus agents, and extended with plugins. Use this sheet for pipeline syntax, the CLI, Docker deployment and backup. Nothing here was run against a live Jenkins: the syntax, commands and paths come from the Jenkins documentation and the official Docker image README, so treat the whole sheet as unverified until you have tried it, and use the built-in Pipeline Syntax snippet generator (/pipeline-syntax on your server) to confirm step arguments.

Documentation: Jenkins docs, Pipeline syntax Project: jenkinsci/jenkins, jenkinsci/docker


Declarative Jenkinsfile #

groovy
pipeline {
    agent { label 'linux' }

    options {
        timeout(time: 30, unit: 'MINUTES')
        timestamps()
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '20'))
    }

    parameters {
        string(name: 'TARGET', defaultValue: 'staging', description: 'Deploy target')
        booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Run the tests')
    }

    triggers {
        pollSCM('H/5 * * * *')
    }

    environment {
        REGISTRY = 'registry.example.com'
        REGISTRY_CREDS = credentials('registry-creds')
    }

    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
        stage('Test') {
            when { expression { params.RUN_TESTS } }
            parallel {
                stage('Unit') {
                    steps { sh 'make test-unit' }
                }
                stage('Lint') {
                    steps { sh 'make lint' }
                }
            }
        }
        stage('Deploy') {
            when { branch 'main' }
            steps {
                sh './deploy.sh "$TARGET"'
            }
        }
    }

    post {
        always { junit allowEmptyResults: true, testResults: 'reports/*.xml' }
        failure { echo 'Build failed' }
        cleanup { cleanWs() }
    }
}

credentials('ID') in environment for a username and password credential also defines NAME_USR and NAME_PSW. cleanWs() comes from the Workspace Cleanup plugin.

Declarative Sections #

SECTIONPURPOSE
agentWhere to run: any, none, { label 'X' }, { docker { image 'IMG' args '-v ...' } }, { dockerfile true }, { kubernetes { ... } } (needs the matching plugin)
stages / stage / stepsThe pipeline body
environmentEnvironment variables, including credentials('ID')
optionstimeout, retry, timestamps, disableConcurrentBuilds, buildDiscarder, skipDefaultCheckout
parametersstring, booleanParam, choice, password, text, file
triggerscron('...'), pollSCM('...'), upstream(...)
toolsTools configured under Manage Jenkins (for example maven, jdk)
whenbranch, tag, expression { }, environment, changeRequest, not, allOf, anyOf; add beforeAgent true to skip agent allocation
parallelRun nested stages at the same time
matrixRun a stage over combinations of axes
inputPause for approval (input message: 'Deploy?')
postalways, success, failure, unstable, changed, fixed, regression, aborted, cleanup

Scripted Pipeline #

groovy
node('linux') {
    try {
        stage('Checkout') {
            checkout scm
        }
        stage('Build') {
            sh 'make build'
        }
        stage('Test') {
            parallel(
                unit: { sh 'make test-unit' },
                lint: { sh 'make lint' }
            )
        }
    } catch (err) {
        currentBuild.result = 'FAILURE'
        throw err
    } finally {
        cleanWs()
    }
}

Use scripted syntax when you need real Groovy control flow; otherwise prefer declarative, which is validated before it runs.

Common Steps #

STEPDESCRIPTION
sh 'cmd' / bat 'cmd' / pwsh 'cmd'Run a shell command (Unix, Windows batch, PowerShell)
sh(script: 'cmd', returnStdout: true).trim()Capture output
checkout scmCheck out the repository that holds the Jenkinsfile
git url: 'URL', branch: 'main'Clone a repository
dir('path') { ... }Run steps in a directory
withEnv(['A=1']) { ... }Set environment variables for a block
withCredentials([string(credentialsId: 'ID', variable: 'TOKEN')]) { ... }Bind a secret for the block (also usernamePassword, file, sshUserPrivateKey)
stash name: 'x', includes: 'dist/**' / unstash 'x'Pass files between stages or agents
archiveArtifacts artifacts: 'dist/**', fingerprint: trueKeep build outputs
junit 'reports/*.xml'Publish test results
timeout(time: 10, unit: 'MINUTES') { ... } / retry(3) { ... }Limit or repeat a block
input message: 'Proceed?'Wait for a person
build job: 'other-job', wait: falseTrigger another job
error 'message'Fail the build
@Library('NAME') _Load a shared library at the top of the Jenkinsfile

Credentials #

KINDUSE
Secret textstring(credentialsId: 'ID', variable: 'VAR') or credentials('ID')
Username and passwordusernamePassword(credentialsId: 'ID', usernameVariable: 'U', passwordVariable: 'P')
SSH keysshUserPrivateKey(credentialsId: 'ID', keyFileVariable: 'KEY')
Secret filefile(credentialsId: 'ID', variable: 'FILE')

Add them under Manage Jenkins, Credentials, scoped to the narrowest folder or system scope that works. Single quote sh strings that use secrets (sh 'echo "$TOKEN" | tool login --stdin') so Groovy does not interpolate the secret into the command line, and see CI/CD Overview.

jenkins-cli #

Download the client jar from your own server and use an API token for authentication.

bash
curl -O https://jenkins.example.com/jnlpJars/jenkins-cli.jar
export JENKINS_URL=https://jenkins.example.com
java -jar jenkins-cli.jar -auth USER:API_TOKEN who-am-i
COMMANDDESCRIPTION
java -jar jenkins-cli.jar -s URL -auth USER:TOKEN helpList every command available on that server
... version / who-am-iServer version, current identity
... list-jobs [FOLDER]List jobs
... build JOB -s -v -p KEY=VALUEStart a job, wait (-s), show output (-v), pass parameters (-p)
... console JOB [BUILD]Show a build’s console output
... get-job JOB > job.xml / create-job NAME < job.xml / update-job JOB < job.xmlExport, create or replace a job definition
... delete-job JOBDelete a job (destructive)
... disable-job JOB / enable-job JOBDisable or enable a job
... list-pluginsInstalled plugins
... install-plugin NAMEInstall a plugin (-restart restarts afterwards)
... safe-restart / restartRestart once running builds finish, or immediately
... quiet-down / cancel-quiet-downStop starting new builds, or resume
... reload-configurationReload configuration from disk
... declarative-linter < JenkinsfileValidate a declarative Jenkinsfile
... groovy = < script.groovyRun a Groovy script on the controller (powerful: admin only)

Authentication options (-auth, -http, -ssh, -webSocket) and the exact command list vary by version and installed plugins: help on your server is authoritative.

Plugins #

TASKHOW
Install in the UIManage Jenkins, Plugins
Install in a Docker imagejenkins-plugin-cli --plugins git workflow-aggregator or -f plugins.txt (one name:version per line)
List what the CLI would installjenkins-plugin-cli --list (flag per the image README, unverified)
Pin versionsPut name:version in plugins.txt so image builds are reproducible
UpdateManage Jenkins, Plugins, Updates; back up first
dockerfile
FROM jenkins/jenkins:lts-jdk21
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN jenkins-plugin-cli -f /usr/share/jenkins/ref/plugins.txt

Running in Docker #

bash
docker run -d --name jenkins \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts-jdk21
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
yaml
services:
  jenkins:
    image: jenkins/jenkins:lts-jdk21
    restart: unless-stopped
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - jenkins_home:/var/jenkins_home
    environment:
      JAVA_OPTS: "-Xmx1g"
volumes:
  jenkins_home:
SETTINGMEANING
Port 8080Web UI
Port 50000Inbound (JNLP) agent connections
/var/jenkins_homeAll state; keep it on a volume
JAVA_OPTSJVM options for the controller
JENKINS_OPTSJenkins options such as --prefix=/jenkins
Pin the tagUse an explicit LTS tag rather than latest

Running builds in Docker from Jenkins needs a Docker CLI and socket (or a Docker cloud). Mounting /var/run/docker.sock gives builds control of the host, so prefer separate agents.

Agents #

METHODDETAILS
Inbound (WebSocket or JNLP) agentCreate the node in Manage Jenkins, Nodes, then run the agent with the node’s secret
jenkins/inbound-agent imagedocker run -d jenkins/inbound-agent -url https://jenkins.example.com -secret SECRET -name AGENT_NAME (add -webSocket to use WebSocket); JENKINS_URL, JENKINS_SECRET and JENKINS_AGENT_NAME environment variables are also read
SSH agentJenkins connects out to the agent over SSH with a credential
Cloud agentsDocker or Kubernetes plugins create agents per build
LabelsSelect with agent { label 'linux && docker' }

Keep the controller’s executors at zero in production and run builds on agents.

Configuration as Code #

The Configuration as Code plugin (JCasC) describes the controller in YAML. Point Jenkins at the file with the CASC_JENKINS_CONFIG environment variable.

yaml
jenkins:
  systemMessage: "Managed by configuration as code"
  numExecutors: 0
unclassified:
  location:
    url: https://jenkins.example.com/

Backup and Restore #

WHATNOTES
$JENKINS_HOME/config.xml and other top level *.xmlGlobal configuration
jobs/Job definitions and build history (history can be large; exclude builds/ if you only need configuration)
nodes/Agent definitions
plugins/*.jpiPlugin files (or record the list in plugins.txt and reinstall)
secrets/ and credentials.xmlNeeded to decrypt credentials; protect the backup
users/User records
Skipworkspace/, caches, logs/
bash
docker run --rm -v jenkins_home:/data:ro -v "$PWD":/backup alpine:3.22 \
  tar czf /backup/jenkins-home.tgz -C /data .

Stop Jenkins (or use safe-restart and a quiet period) for a consistent copy, and test a restore. Moving to a new server means restoring the same secrets/ along with credentials.xml.

Useful URLs #

PATHPURPOSE
/pipeline-syntaxSnippet generator for step arguments
/manageManage Jenkins
/scriptScript console (Groovy on the controller, admin only)
/safeRestartRestart when idle (POST in current versions)
/quietDown / /cancelQuietDownStop or resume starting builds
/restartRestart now (POST)

Troubleshooting #

SYMPTOMFIX
Locked out or forgot the admin passwordRead secrets/initialAdminPassword for a new install; otherwise disable security temporarily in config.xml with the controller stopped (restore it straight after)
Pipeline waits for an executorNo agent with that label, or all busy; check Manage Jenkins, Nodes
Secret printed in the logUse withCredentials or credentials(); masking only covers the exact string
script not permittedSandbox blocks the method: use a plugin step, or an admin approves it under In-process Script Approval
Plugin upgrade broke JenkinsRestore plugins/ from backup or pin the earlier version in plugins.txt
Agent will not connectCheck -url, secret, the node name, and that port 50000 (or WebSocket over 8080) is reachable
Build disk fills upSet buildDiscarder, clean workspaces, move JENKINS_HOME to larger storage

See Also #

Search all sheets

Tip: / or Ctrl/Cmd+K to open, Esc to close.