# How to Set Up Jenkins Agents: A Complete Guide to Distributed Builds

> Master Jenkins agents and distributed builds. Learn to configure and launch agents using JNLP SSH or containers for scalable CI/CD.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: how-to-guide
- Published: 2026-07-29

---

**Jenkins agents extend your controller's capacity by executing builds on remote machines, configured through the `hudson.model.Node` abstraction and launched via JNLP, SSH, or container protocols defined in `jenkins.AgentProtocol`.**

Setting up Jenkins agents (formerly called "slaves") allows you to distribute build workloads across multiple machines, preventing your controller from becoming a bottleneck. According to the jenkinsci/jenkins source code, the entire distributed architecture revolves around a few core classes that handle everything from node abstraction to wire-level communication protocols.

## Core Architecture of Jenkins Agents

Before configuring agents, you need to understand how Jenkins models distributed builds internally. The source code in `core/src/main/java` defines clear boundaries between the controller, the agent nodes, and their communication channels.

### The Node Abstraction (`hudson.model.Node`)

Every machine capable of running builds in Jenkins—whether the controller itself or a remote agent—is represented as a `Node`. The abstract class `hudson.model.Node` (located in [`core/src/main/java/hudson/model/Node.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/Node.java)) defines the contract for workspace allocation, label assignment, and resource management. When you set up a Jenkins agent, you are essentially creating a new instance of a concrete `Node` subclass that the controller can manage.

### Agent Implementation Classes

Remote agents are implemented through two key classes in the `hudson.slaves` package:

- **`Slave`** ([`core/src/main/java/hudson/slaves/Slave.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/slaves/Slave.java)): The concrete implementation of a remote build node. It stores configuration like the remote filesystem root (`remoteFS`) and the launch method.

- **`Computer`** ([`core/src/main/java/hudson/slaves/Computer.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/slaves/Computer.java)): Represents the controller-side view of an active agent connection. This object manages the live channel to the agent process and tracks online/offline status, resource utilization, and build activity.

### Communication Protocols (`jenkins.AgentProtocol`)

Agents communicate with the controller through protocols defined in [`core/src/main/java/jenkins/AgentProtocol.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/AgentProtocol.java). The default implementation uses JNLP (Java Network Launch Protocol) with the Remoting library, establishing a bidirectional channel (`hudson.remoting.Channel`) between the controller and agent. This channel handles command execution, file transfers, and log streaming.

## Prerequisites for Setting Up Jenkins Agents

Before creating agent configurations in the Jenkins UI or via code, ensure your infrastructure meets these requirements:

1. **Java Runtime**: The remote machine must have a JDK installed that matches or exceeds the version running on the controller.

2. **Network Connectivity**: The agent must reach the controller on the TCP port configured for agent communication (default is 50000, configurable via `--agentPort`).

3. **Filesystem Permissions**: The `remoteFS` directory (typically `/home/jenkins` or `C:\jenkins`) must exist and be writable by the user running the agent process.

4. **Authentication**: For JNLP agents, you need the secret token generated by the controller, stored securely in the controller's `SecretStore`.

## Method 1: Launching Agents via JNLP

The JNLP method is the most common approach for permanent agents. In this model, the agent initiates the connection to the controller using the `agent.jar` (also called `remoting.jar`) file.

First, download the agent jar from your controller:

```bash
curl -O http://<controller-host>:8080/jnlpJars/agent.jar

```

Then launch the agent with the connection parameters provided by Jenkins:

```bash
java -jar agent.jar \
  -jnlpUrl http://<controller-host>:8080/computer/<agent-name>/jenkins-agent.jnlp \
  -secret <agent-secret> \
  -workDir /home/jenkins

```

This establishes the Remoting channel defined in `AgentProtocol`. The `AgentComputerUtil` class ([`core/src/main/java/jenkins/agents/AgentComputerUtil.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/agents/AgentComputerUtil.java)) helps the controller locate and manage the corresponding `Computer` object once the connection is established.

## Method 2: Connecting Agents via SSH

For Linux/Unix environments, you can configure Jenkins to launch agents automatically via SSH. This method uses `hudson.slaves.CommandLauncher` to establish the connection.

When you select "Launch agent via SSH" in the node configuration, Jenkins uses the CommandLauncher to execute a startup command on the remote host:

```bash
ssh jenkins@agent.example.com java -jar /path/to/agent.jar

```

You can also configure this programmatically using the `CommandLauncher` class:

```groovy
import hudson.model.Node
import hudson.slaves.Slave
import hudson.slaves.CommandLauncher

def launcher = new CommandLauncher(
    "ssh -i /var/jenkins/.ssh/id_rsa jenkins@agent.example.com " +
    "'java -jar /home/jenkins/agent.jar'"
)

def agent = new Slave(
    "linux-agent-01",
    "/home/jenkins",
    launcher
)

Jenkins.instance.addNode(agent)

```

## Method 3: Running Agents in Docker Containers

For cloud-native or containerized environments, you can run agents using the official `jenkins/agent` Docker image. This approach is particularly effective when combined with the Kubernetes or Docker Swarm plugins.

Run a containerized agent with the required environment variables:

```bash
docker run -d \
  --name jenkins-agent \
  -e JENKINS_URL=http://jenkins-controller:8080 \
  -e JENKINS_SECRET=<secret-from-ui> \
  -e JENKINS_AGENT_NAME=docker-agent-01 \
  -e JENKINS_AGENT_WORKDIR=/home/jenkins \
  jenkins/agent:latest

```

The container automatically downloads the `agent.jar` from the controller and initiates the JNLP connection using the Remoting library.

## Automating Agent Creation with Groovy

You can script agent creation using Jenkins' Groovy console or pipeline scripts. This is useful for Infrastructure-as-Code setups:

```groovy
import jenkins.model.Jenkins
import hudson.slaves.Slave
import hudson.slaves.DumbSlave
import hudson.slaves.JNLPLauncher

// Create a JNLP-based agent
def launcher = new JNLPLauncher()
def slave = new DumbSlave(
    "automated-agent",           // name
    "Auto-provisioned agent",    // description
    "/var/jenkins",              // remoteFS
    "1",                         // numExecutors
    Node.Mode.NORMAL,           // mode
    "linux docker",             // labels
    launcher,                   // launch method
    null                        // retention strategy
)

Jenkins.instance.addNode(slave)
println "Agent ${slave.name} configured successfully"

```

This creates a node configuration in the controller's `Node` list without requiring UI interaction.

## Summary

- **Jenkins agents** are remote `Node` instances that offload build execution from the controller, implemented in `hudson.slaves.Slave` and managed via `hudson.slaves.Computer`.

- **Communication** happens through the Remoting library and `jenkins.AgentProtocol`, typically over JNLP on port 50000.

- **Launch methods** include JNLP (agent-initiated), SSH (controller-initiated), and container-based deployments using the `jenkins/agent` image.

- **Configuration** requires matching Java versions, writable remote filesystem directories, and proper network connectivity between agent and controller.

- **Automation** is supported through Groovy scripting using `Jenkins.instance.addNode()` and launcher classes like `CommandLauncher` or `JNLPLauncher`.

## Frequently Asked Questions

### What is the difference between a Jenkins agent and a node?

In the Jenkins architecture, **node** is the generic term defined in `hudson.model.Node` that represents any machine capable of running builds, including the controller itself. An **agent** (historically called a slave) is a specific type of node that runs on a remote machine separate from the controller. The controller is also technically a node, but when administrators refer to "nodes" in the context of scaling, they typically mean agents.

### Which launch method should I use for cloud environments?

For **cloud environments** (AWS, Azure, GCP, or Kubernetes), use either the **JNLP** method with the official Docker image or the **container plugin** approach. Cloud plugins like the Kubernetes Plugin automatically handle agent provisioning using the `jenkins/agent` container image. For static cloud VMs, JNLP with the `-jnlpUrl` parameter works best because it handles NAT and firewall scenarios where inbound SSH might be blocked.

### How do I troubleshoot agent connection failures?

Check three areas based on the source code implementation:

1. **Network**: Verify the agent can reach the controller on the JNLP port (default 50000) using `telnet controller-host 50000`.

2. **Java version**: Ensure the agent is running a JDK version compatible with the controller's Remoting library version.

3. **Secret**: Confirm the secret token matches exactly what Jenkins generated in the node configuration screen. The secret is validated in `AgentProtocol` during the handshake phase.

4. **Logs**: Check the agent process output for `hudson.remoting` exceptions indicating channel establishment failures.

### Can I set up Jenkins agents on Windows machines?

Yes. Windows agents follow the same architecture using `hudson.slaves.Slave` but require Windows-specific launch methods. You can use **JNLP** with `agent.jar` launched from a PowerShell or Command Prompt, or configure the **SSH** launcher if OpenSSH is installed on Windows. For production Windows environments, the **Windows Service** wrapper is often used to run the agent as a background service, connecting via JNLP to the controller.