Controller & agent architecture

Why builds never run on the controller.

Beginner14 min · lesson 2 of 15

A healthy Jenkins has two kinds of machine. The controller is the brain: it serves the web UI, stores configuration and job history, schedules work, and orchestrates everything — but it should run no builds itself. Agents (historically "nodes" or "slaves") are the workers: they connect to the controller and actually execute the build steps. The controller decides; the agents do.

Controller and agents
controller (the brain — runs no builds)
web UI + API
where you configure and watch
scheduler
assigns jobs to agents
JENKINS_HOME
all config + history + secrets
agents (the workers)
execute build steps
compile, test, package
ephemeral where possible
a clean workspace per build
The controller holds every credential and job. That is exactly why builds must never run on it.

Why builds never run on the controller

This is the single most important architectural rule in Jenkins, and it is a security rule. The controller holds every credential, every job definition, and the keys to your whole delivery pipeline. A build is arbitrary code — a Jenkinsfile, a test, a dependency — and if that code runs on the controller, a malicious or compromised build can read every secret and take over the entire instance. Keep builds on agents so a poisoned build is contained to a disposable worker.

terminal
# lock the built-in node to zero executors so nothing can build on the controller
# Manage Jenkins → Nodes → Built-In Node → # of executors: 0
# then all work is forced onto agents (labelled, e.g. "linux", "docker")

Agents connect to the controller in one of two directions: the controller launches them (over SSH), or the agent dials in (inbound, via a JNLP/WebSocket connection) — useful when the agent is behind a firewall. Modern setups make agents ephemeral, spinning up a fresh container or cloud VM per build and destroying it after, so every build starts from a clean, uncontaminated workspace.

Zero executors on the controller
A fresh Jenkins often defaults the built-in node to two executors, meaning builds run on the controller out of the box. Set it to 0 on day one and label your agents. This one change is the difference between "a bad build breaks a worker" and "a bad build owns everything."