Builds need the right OS, tools and isolation, and the agent directive is how you get them.
The agent directive appears at the top of the pipeline or on a stage:
agent any: any executor.agent { label 'linux && docker' }: a node whose labels match the expression (&&,||,!allowed).agent { docker { image 'node:22' } }: run the steps inside a container on a node with Docker (Docker Pipeline plugin). Jenkins mounts the workspace into the container, so files persist across steps. Addargsfor extradocker runflags andreuseNode trueto stay on the outer node's workspace.agent { dockerfile true }: build the image from the repository's Dockerfile first.agent { kubernetes { yaml ... } }: a throwaway pod per build (Kubernetes plugin).agent none: no global agent; each stage declares its own. Use it when stages need different platforms, or when a stage waits for approval and should not hold an executor.
Containers give every build a clean, versioned toolchain without installing tools on agents: the agent only needs Docker. Pin image tags so a new latest doesn't break builds.
Agents connect to the controller either by the controller launching them over SSH, or by the agent connecting inbound (TCP port 50000 or WebSocket). Cloud plugins provision agents on demand and remove them when idle.
Example
pipeline {
agent none
stages {
stage('Backend') {
agent { docker { image 'maven:3.9-eclipse-temurin-21' } }
steps { sh 'mvn -B -q verify' }
}
stage('Frontend') {
agent { docker { image 'node:22-alpine'; args '-e CI=true' } }
steps { sh 'npm ci && npm test' }
}
stage('Windows smoke test') {
agent { label 'windows' }
steps { bat 'run-smoke.cmd' }
}
}
}Remember
- agent { label '...' } picks nodes by label expression
- agent { docker { image ... } } runs steps in a pinned container
- agent none + per-stage agents mixes platforms and frees executors
Watch out for
- Installing every toolchain on every agent instead of using pinned container images.