Self-hosted service
jenkinsci/docker-agents avatar
jenkinsci/docker-agents

jenkinsci/docker-agents: the base and inbound agent images, and what their build system actually commits you to

Jenkins agent (base image) and inbound agent Docker images

340 stars249 forksPowerShellMIT

At a glance

What is it?
This repository defines two families of Jenkins agent images (a bare agent base and an inbound agent that dials back to the controller) across Alpine, Debian, RHEL UBI9 and Windows bases, with JDK 21 and 25 variants. The interesting part is not the images themselves but the buildx bake graph and Makefile wrapper that decide which of the 32 targets you can actually produce on your machine.
Who is it for?
Adopt this if you run Jenkins controllers and want agent images that track upstream remoting versions, and especially if you need Windows or RHEL UBI9 variants you would rather not maintain yourself. Do not adopt it if your agents need a preinstalled toolchain, because these images ship a JDK and agent.jar and nothing else; you will be layering on top regardless, and at that point you are maintaining a derivative of a repository that publishes new tags on its own schedule.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PowerShell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

Two image families, and the distinction that matters when you pick one

The repository publishes two things, and the README is explicit that they are not interchangeable. The agent image is described as a base image for Docker that includes a JDK and the Jenkins agent executable, agent.jar. The inbound-agent image is built on top of agent and is intended for agents that use TCP or WebSockets to establish an inbound connection to the Jenkins controller. That word inbound is the whole design decision. An inbound agent starts inside the container and connects outward to the controller, which means the controller does not need to reach the agent's network namespace. If your Jenkins controller sits outside the Docker network your agents run on, or behind a NAT boundary, the inbound-agent image is the one that works without extra plumbing. If you are using the Docker plugin's attach model or a JNLP-style launch where the controller initiates, the plain agent base is the layer you build on. The README points to separate files, README_agent.md and README_inbound-agent.md, for each, so the two families are documented separately rather than collapsed into one page. Treat the base agent image as a starting point, not a runnable agent: it carries the JDK and agent.jar, and the connection logic belongs to the inbound variant.

The build matrix is the product: 16 targets per family across four base OS families

What this repository really ships is a combinatorial target graph. Running make list on Linux prints the targets matching your current OS and architecture, and the README shows the result for linux/arm64: agent and inbound-agent each in alpine, debian and rhel_ubi9 variants, each crossed with jdk21 and jdk25. That is twelve Linux targets. make list-all widens the view and adds Windows: nanoserver-ltsc2022, nanoserver-ltsc2025, windowsservercore-ltsc2022 and windowsservercore-ltsc2025, again for both families and both JDK versions. The full listing in the README runs to 32 target names. The OS and ARCH variables let you re-filter that list, so OS=windows ARCH=amd64 make list returns only the Windows targets. This is a buildx bake graph, not a set of hand-written docker build calls. The README shows make show piping docker buildx bake --file docker-bake.hcl --progress=quiet --print all through jq, and the resulting JSON exposes group entries (alpine, debian, rhel_ubi9, linux, default) alongside target entries carrying context, dockerfile, args, tags, target, platforms and output. The alpine target in that output, for example, declares ALPINE_TAG 3.24.1 and a VERSION argument, and lists tags under docker.io/jenkins/agent including alpine, latest-alpine, alpine3.24 and latest-alpine3.24. The consequence for anyone forking this: your customisation point is docker-bake.hcl and the per-flavour Dockerfiles, not a single top-level Dockerfile.

Getting a build running: make targets, OS and ARCH variables, and the ON_TAG switch

The documented entry points are all Makefile targets. To see what your machine would build, run make list; to see everything including targets your architecture cannot build, run make list-all. To build one image, the README gives the pattern make build-<AGENT_TYPE>_<LINUX_FLAVOR>_<JDK_VERSION> and a concrete example: make build-inbound-agent_debian_jdk25. To build everything supported by your current architecture, make build. To test everything, make test, and to test one image, make test-inbound-agent_debian_jdk25 following the same naming pattern. For cross-architecture work there is make multiarchbuild, which the README says builds all images for your OS even those unsupported by your current architecture. Two variables change what you see rather than what you build. OS and ARCH filter the target list, as in OS=windows ARCH=amd64 make list. ON_TAG controls whether the tag listing includes everything created on publication; the README notes you must set ON_TAG to true to see all tags, and shows ON_TAG=true BUILD_NUMBER=3 make tags as the way to inspect them. That BUILD_NUMBER detail is worth noting: tag output depends on a build number being supplied, so the tag set is not fully derivable from the repository state alone.

Where this breaks down: architecture filtering, Windows hosts, and the empty-image problem

The first limitation is stated almost in passing. make build only builds images supported by your current architecture, and make list filters to your current OS and architecture by default. If you develop on linux/amd64 and your fleet includes linux/arm64, the default targets are the wrong ones; you need make multiarchbuild or an explicit OS and ARCH pair, and multiarch builds need buildx with the appropriate builders configured, which this README does not walk through. The second is the Windows side. The repository defines nanoserver and windowsservercore targets, but the README's build and test instructions are headed Building and testing on Linux, and the make list example for Windows is shown as a listing operation, not a build. Nothing in the supplied material describes building those Windows images from a non-Windows host, so treat Windows target support as defined-but-not-demonstrated here. The third is the one that catches people after adoption: these images contain a JDK and agent.jar. They do not contain Maven, Gradle, Node, Python, a C toolchain, or your cloud CLI. Every real pipeline layers on top, which means you inherit both the upstream image's update cadence and your own Dockerfile's drift. The fourth is version coupling. The docker-bake.hcl output ties a VERSION argument to a specific remoting release, and the release names in this repository look like remoting versions (3391.va_37fa_a_305d6d and similar). If your controller and agent remoting versions diverge, the connection behaviour is your problem to diagnose, and this repository does not provide a compatibility matrix.

How it compares with writing your own agent Dockerfile

The obvious alternative is a Dockerfile that starts from a plain JDK base such as eclipse-temurin, downloads agent.jar from the Jenkins update centre, and sets the entrypoint yourself. That approach gives you total control over the JDK vendor, the base distribution and the layer order, and it is roughly a dozen lines. The difference in practice is maintenance surface. This repository maintains the base OS variants (Alpine, Debian, RHEL UBI9, two Windows generations), two JDK lines, and the tag scheme that maps them, and it publishes new builds as remoting versions move. A hand-written Dockerfile has none of that machinery, but it also has no one updating the pinned agent.jar for you, and no make test target to run against a change. The second alternative is the Jenkins Kubernetes plugin's default agent image, or a cloud provider's managed build agents. Those move the agent lifecycle out of your Docker infrastructure entirely. What you give up is the ability to bake a specific toolchain into the image and control the base OS, which is exactly the reason teams end up in this repository in the first place. The honest framing: this repository is the middle option, more maintained than a personal Dockerfile but thinner than a purpose-built CI image.

Maintenance cost, release cadence and what the MIT licence does and does not cover

The release list shows three releases in roughly ten days in late August and early September 2026, with version strings that track remoting (3391.va_37fa_a_305d6d appears twice, at -1 and -2, and 3386.v353e57a_1b_ea_0-3 precedes them). That cadence is the maintenance story: if you consume jenkins/inbound-agent directly from Docker Hub, you get updates without doing anything, and the cost is that a tag can move under you. If you fork and build your own, you own the rebase, and the build system's shape (docker-bake.hcl plus per-flavour Dockerfiles plus a Makefile) means a rebase touches the bake file and the Dockerfiles rather than one file. Pin by digest or by the versioned tags shown in the bake output (alpine3.24, latest-alpine3.24 and similar) rather than by latest-alpine if reproducibility matters. On licensing: the repository is MIT, which is permissive and places few conditions on redistribution. That covers the repository's own files. It does not settle the licences of the base images it builds on. Alpine, Debian, RHEL UBI9 and the Windows base images each carry their own terms, and the JDK distributions bundled into the images carry theirs. Redistributing a rebuilt image is a question about all of those layers, not about this repository's MIT file. That is a question for your own legal review, not something the README answers.

Editorial conclusion

Adopt this if you run Jenkins controllers and want agent images that track upstream remoting versions, and especially if you need Windows or RHEL UBI9 variants you would rather not maintain yourself. Do not adopt it if your agents need a preinstalled toolchain, because these images ship a JDK and agent.jar and nothing else; you will be layering on top regardless, and at that point you are maintaining a derivative of a repository that publishes new tags on its own schedule. Before committing, run make list-all to confirm the targets matching your OS and architecture, and check whether the JDK version you need is present in both the agent and inbound-agent families rather than only one.

Official sources

  1. jenkinsci/docker-agents on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes