The orchestration of continuous integration and continuous delivery (CI/CD) pipelines necessitates a robust, scalable, and isolated execution environment. Jenkins, the industry-standard automation server, achieves this through the use of agents—distributed nodes that execute the actual build tasks, tests, and deployments commanded by the Jenkins controller. Utilizing Docker as the underlying technology for these agents transforms the infrastructure from a static set of servers into a dynamic, ephemeral pool of resources. By leveraging Docker images, organizations can ensure that every build starts from a clean, known state, eliminating the "it works on my machine" phenomenon and providing the ability to scale horizontally across diverse operating systems and Java versions. This deep dive explores the technical nuances of the Jenkins agent Docker ecosystem, encompassing the base images, the inbound connection mechanism, and the SSH-based launch strategies.
The Hierarchy of Jenkins Agent Docker Images
The Jenkins ecosystem provides a layered approach to agent images, allowing developers to choose between a generic base and a specialized, pre-configured inbound agent. Understanding the distinction between these images is critical for selecting the correct deployment strategy.
The Base Agent Image (jenkins/agent)
The jenkins/agent image serves as the foundational building block for the entire agent ecosystem. This image is not designed to be a standalone runtime for all use cases but rather a specialized environment containing the essential components required for a node to communicate with the Jenkins controller.
- Direct Fact: The
jenkins/agentimage includes the Java Development Kit (JDK) and the Jenkins agent executable known asagent.jar. - Technical Layer: The
agent.jaris an instance of the Jenkins Remoting library. This library manages the communication protocol between the controller and the agent, handling the serialization of tasks and the return of build results. The Java version bundled with the image varies based on the platform and the specific tag used, ensuring compatibility with the controller's own Java runtime. - Impact Layer: Because this image is a base, it provides a lightweight footprint. Users can use it to launch agents via the "execution of command on the controller" method, where the controller pushes the agent logic to the node, or use it as a parent image to build custom agents with specific tools (like Python, Go, or Node.js) pre-installed.
- Contextual Layer: This base image is the direct ancestor of the
jenkins/inbound-agent. While the base agent is flexible, the inbound agent adds the specific logic required for the agent to "call home" to the controller.
The Inbound Agent Image (jenkins/inbound-agent)
The jenkins/inbound-agent image is a specialized derivative of the base agent image. It is specifically engineered for scenarios where the agent is launched externally and must establish a connection to the Jenkins controller.
- Direct Fact: This image uses TCP or WebSockets to establish an inbound connection to the Jenkins controller.
- Technical Layer: Unlike traditional agents that the controller connects to, the inbound agent initiates the handshake. It requires specific parameters—the controller URL, a secret token, and the agent name—to authenticate and register itself. It relies on the Jenkins Remoting library bundled in the base image to maintain a persistent connection.
- Impact Layer: This architecture is ideal for agents residing behind firewalls or in NAT (Network Address Translation) environments where the controller cannot reach the agent's IP address, but the agent can reach the controller's public endpoint.
- Contextual Layer: The configuration of this image involves setting environment variables like
JENKINS_SECRETand utilizing theJENKINS_URLto locate the master server.
Comprehensive Image Matrix and Versioning
Jenkins provides a wide array of images to support different operating systems and Java versions. This ensures that the agent environment matches the requirements of the application being built.
| Image Series | OS Base | Java Version | Intended Use |
|---|---|---|---|
| agent_alpine | Alpine Linux | JDK 21, JDK 25 | Lightweight base for Linux agents |
| agent_debian | Debian | JDK 17, JDK 21, JDK 25 | Standard Linux base with broader tool support |
| agentrhelubi9 | RHEL UBI9 | JDK 17, JDK 21, JDK 25 | Enterprise Linux environment |
| inbound-agent_alpine | Alpine Linux | JDK 21, JDK 25 | Inbound agents on lightweight Linux |
| inbound-agent_debian | Debian | JDK 17, JDK 21, JDK 25 | Inbound agents on standard Linux |
| inbound-agentrhelubi9 | RHEL UBI9 | JDK 17, JDK 21, JDK 25 | Inbound agents on Enterprise Linux |
For developers using the jenkinsci/docker-agents repository, the build process is managed via a docker-bake.hcl file. This allows for the simultaneous creation of multiple architectures (such as linux/arm64) and versions. The available images can be listed using the make command.
The following commands are used to inspect and list the available targets within the build environment:
bash
make list
When executed, this triggers a sequence of operations:
bash
+ make --silent listarch-arm64
+ make --silent showarch-arm64
+ jq -r '.target | keys[]'
+ make --silent show
+ jq --arg arch linux/arm64 '.target |= with_entries(select(.value.platforms | index($arch)))'
+ make --silent show-all
+ docker buildx bake --file docker-bake.hcl --progress=quiet --print all
To see a complete list of every possible image target, the following command is used:
bash
make list-all
Deployment Strategy: Inbound Agents
The inbound agent strategy is used when the Docker container is managed by an external orchestrator (like Docker Compose or Kubernetes) and needs to attach itself to the Jenkins controller.
Controller-Side Configuration
Before the container is launched, the agent must be registered within the Jenkins UI:
- Navigate to Manage Jenkins > Nodes.
- Select New Node, provide a name, select Permanent Agent, and click Create.
- Under the Launch method, select "Launch agent by connecting it to the controller".
- Save the configuration.
At this stage, the agent is registered but remains offline. Jenkins will generate a JENKINS_SECRET which is required for the container to authenticate. Additionally, the administrator must ensure the agent port (default 50000) is open in the security settings:
Manage Jenkins > Security > Agent.
Execution Commands for Linux and Windows
The execution of the inbound agent differs by platform. A critical technical detail for Linux is the use of the --init flag. This flag ensures that the container uses an init process to handle zombie process reaping, which is essential for the longevity of the agent.
For a standard Linux agent:
bash
docker run --init jenkins/inbound-agent -url http://jenkins-server:port <secret> <agent name>
For a Linux agent requiring a specific working directory:
bash
docker run --init jenkins/inbound-agent -url http://jenkins-server:port -workDir=/home/jenkins/agent <secret> <agent name>
For Windows agents using Windows Server Core 2019:
bash
docker run jenkins/inbound-agent:windowsservercore-ltsc2019 -Url http://jenkins-server:port -Secret <secret> -Name <agent name>
For Windows agents with a specific working directory:
bash
docker run jenkins/inbound-agent:windowsservercore-ltsc2019 -Url http://jenkins-server:port -WorkDir=C:/Jenkins/agent -Secret <secret> -Name <agent name>
Advanced Configuration via Environment Variables
To fine-tune the agent's behavior without modifying the entrypoint command, several environment variables can be employed:
JENKINS_JAVA_BIN: Specifies the path to a specific Java executable if the default one inPATHorJAVA_HOMEis insufficient.JENKINS_JAVA_OPTS: Used to pass Java options to the remoting process.JENKINS_AGENT_FILE: Defines the location of theagent.jar. The default is/usr/share/jenkins/agent.jar.REMOTING_OPTS: A generic variable to pass additional CLI options to theagent.jar.JENKINS_URL: An alternative to the-urlflag to specify the Jenkins server address.JENKINS_TUNNEL: Used to specify aHOST:PORTfor tunneling connections.
Deployment Strategy: SSH-Based Agents
The SSH-based approach reverses the connection logic. In this model, the Jenkins controller initiates an SSH connection to the Docker container to launch the agent.
Prerequisites and Infrastructure
To implement this setup, the following components are required:
- Java installation
- Jenkins installation
- Docker installation
- A valid SSH key pair
The SSH key pair is generated using the ssh-keygen tool. This can be performed on the controller, the host machine, or a separate developer machine.
Credential Configuration in Jenkins
The controller must possess the private key to authenticate with the agent container. This is configured as follows:
- Go to Manage Jenkins > Security > Credentials.
- Select Add Credentials from the global store.
- Set the Kind to "SSH username with private key".
- Use "jenkins" as the username.
- Paste the content of the private key file (e.g.,
~/.ssh/jenkins_agent_key). - Enter the passphrase if one was created during
ssh-keygen.
Launching the SSH Agent Container
The jenkins/ssh-agent image is designed to act as an SSH server. When the container starts, it uses the provided public key to allow access.
For a basic deployment:
bash
docker run -d --rm --name=agent1 -p 22:22 -e "JENKINS_AGENT_SSH_PUBKEY=<your_public_key>" jenkins/ssh-agent:alpine-jdk21
For a deployment utilizing a specific Docker network (e.g., a network named "jenkins"):
bash
docker run -d --rm --name=agent1 --network jenkins -p 22:22 -e "JENKINS_AGENT_SSH_PUBKEY=<your_public_key>" jenkins/ssh-agent:jdk21
Finalizing the Node Connection
Once the container is running, the administrator must link it to the controller:
- Navigate to Manage Jenkins > Nodes > New Node.
- Enter the Node name and select Permanent Agent.
- Configure the following fields:
- Remote root directory: The path where Jenkins will store files on the agent.
- Labels: Used to group agents (e.g.,
linux,docker,high-memory). - Usage: Determines if the agent is used for any job or only specific ones.
- Launch method: Select "Launch agent via SSH".
- Host: The IP address of the container.
- Credentials: Select the "jenkins" SSH credential created previously.
- Host Key verification Strategy: Define how the controller verifies the agent's SSH key.
- Save and select the agent node to view its status.
To verify if the container is running and retrieve its IP address for the Host field, use the following commands:
bash
docker ps
bash
docker container inspect agent1 | Select-String -Pattern '"IPAddress": "\d+\.\d+\.\d+\.\d+"'
If the agent does not connect automatically, the "Relaunch agent" option should be used. Success is confirmed in the logs with the message: Agent successfully connected and online.
Analysis of Agent Categorization and Labels
A critical component of managing a Docker-based agent fleet is the use of Labels. Labels are not merely metadata but are functional filters used by the Jenkins scheduler to assign builds to the correct environment.
- Direct Fact: Labels group agents based on specific criteria like OS or hardware.
- Technical Layer: When a pipeline is defined, the
agent { label 'docker' }block tells the controller to look for any available node that possesses the "docker" label. If multiple agents have the same label, the controller distributes the load among them. - Impact Layer: This allows for a heterogeneous build farm. For example, a job requiring a high-memory environment can be targeted to an agent labeled
high-memory, while a Windows-specific build is targeted to an agent labeledwindows. - Contextual Layer: This mapping allows the
jenkins/ssh-agentorjenkins/inbound-agentto be deployed in various flavors (Alpine, Debian, RHEL) while the pipeline remains agnostic of the underlying image, relying only on the label.
Conclusion: Technical Synthesis of Docker Agent Architectures
The transition from static agents to Docker-based agents represents a shift toward immutable infrastructure in the CI/CD domain. The choice between jenkins/agent (base), jenkins/inbound-agent (pull), and jenkins/ssh-agent (push) depends entirely on the network topology and the desired level of control.
The inbound agent is the superior choice for cloud-native environments and Kubernetes, as it allows the agent to be treated as a disposable resource that registers itself upon startup. The SSH agent, conversely, provides the controller with more direct control over the agent's lifecycle and is often easier to set up in traditional virtualized environments.
The importance of the --init flag in Linux environments cannot be overstated, as it prevents the accumulation of zombie processes that would eventually exhaust the PID limit of the host system. Furthermore, the availability of multiple Java versions (JDK 17, 21, 25) across different OS bases (Alpine, Debian, RHEL) ensures that Jenkins can support legacy applications while simultaneously adopting the latest JVM features. By utilizing labels and a structured image hierarchy, organizations can create a scalable, resilient, and highly specialized execution environment that minimizes configuration drift and maximizes throughput.