feat(workers): install the GitHub CLI in coding agent images - #1403
Draft
Cedric Vidal (cedricvidal) wants to merge 2 commits into
Draft
Cedric Vidal (cedricvidal) wants to merge 2 commits into
Cedric Vidal (cedricvidal) wants to merge 2 commits into
Conversation
Coding agents are routinely asked to work with issues, branches and pull
requests, but `gh` was not available in any worker image, so a task that
needed it could only fail or fall back to hand-rolled API calls.
Install it alongside the other system tools each image already ships
(Python, Go, .NET, Java, Maven, Gradle, PowerShell), pinned to 2.100.0 for
reproducible builds:
- coder-acp-copilot and coder-acp-claude-code: fold the release tarball into
the existing toolchain layer, reusing its `ARCH` so amd64 and arm64 both
resolve (gh's asset names match `dpkg --print-architecture` exactly). The
layer ends in `gh --version` so a bad URL fails the build instead of
silently producing an image without it.
- coder-acp-copilot-windows: install through Chocolatey next to git. No
version check here, because the Chocolatey shim directory only joins PATH
via the later ENV, so `gh` is not yet invokable at that layer.
`GH_VERSION` is exported at runtime so the agent version registration can
report it next to COPILOT_CLI_VERSION.
Verified by building the coder-acp-copilot `base` stage and running the
resulting image:
gh version 2.100.0 (2026-09-03)
GH_VERSION=2.100.0
/usr/local/bin/gh
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 507f8ebd-cc32-489c-afca-8941c5f8dba1
Test Results (Node.js 22)test: Run #57
🎉 All tests passed! |
The coder services mount the host Docker socket and set DOCKER_HOST so the
agent can run containers during a task. `group_add: ${DOCKER_GID:-0}` gives
the right GID, but that is only half of what the socket needs.
Where the daemon host enforces SELinux — a podman machine always does, and
RHEL/Fedora Docker Engine can — the worker runs as `container_t` while the
socket is labelled `var_run_t`, and policy denies the connect. The agent then
cannot run containers at all, and the failure is easy to misread: it surfaces
as `permission denied ... /var/run/docker.sock`, which looks like a GID
problem that DOCKER_GID has already solved. Even `stat` on the socket is
denied, which is the tell that it is the label and not the mode.
Measured on a podman machine with SELinux enforcing, mounting the socket into
the copilot worker image:
security_opt group_add 0 result
(none) no denied
label=disable no denied
label=type:container_runtime_t no denied
(none) yes denied
label=disable yes OK
label=type:container_runtime_t yes OK
So both are required. Add `security_opt: label=disable` next to the existing
group_add. Docker ignores label options on hosts without SELinux, so this is
a no-op under Docker Desktop and leaves those setups unchanged.
`label=type:container_runtime_t` works equally well and keeps the container
confined, which is preferable in principle, but it depends on container-selinux
providing that type and fails closed when it does not. For a local development
stack the portable option is the better default; the alternative is noted in a
comment.
Verified by recreating coder-acp-copilot from the compose files alone: the
container reports SecurityOpt ["label=disable"], GroupAdd ["0"], and `docker
ps` from inside the agent's user now succeeds.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 507f8ebd-cc32-489c-afca-8941c5f8dba1
Test Results (Node.js 22)test: Run #58
🎉 All tests passed! |
Cedric Vidal (cedricvidal)
marked this pull request as draft
September 14, 2026 05:36
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Coding agents are routinely asked to work with issues, branches and pull requests, but
ghis not present in any worker image. A task that needs it can only fail, or fall back to hand-rolled REST calls.Every coder image already ships a broad toolchain — Python, uv, git, PowerShell, Go, .NET, Rust, Java, Maven, Gradle — so the GitHub CLI is a natural and missing member of that set.
Change
Install
gh, pinned to 2.100.0, in the three agent worker images:coder-acp-copilotcoder-acp-claude-codecoder-acp-copilot-windowschoco install -y gh --version=2.100.0, next to gitDetails worth noting for review:
ARCH=$(dpkg --print-architecture).gh's release asset names useamd64/arm64, which match that output exactly, so both build architectures resolve without a newcaseblock.gh --version, so a bad URL or a yanked release fails the build rather than silently producing an image without the tool.PATHvia the laterENV, soghis not yet invokable at that layer — the same reason the existingchoco install -y gitdoes not verify either.GH_VERSIONis exported at runtime so agent version registration can report it alongsideCOPILOT_CLI_VERSION.Validation
Built the
coder-acp-copilotbasestage and ran the resulting image:The install layer was also built standalone on
arm64to confirm the asset-name and architecture handling.I confirmed the Chocolatey
ghpackage exists at 2.100.0 (it is also the current version there), but I could not build the Windows image locally, so that one is unverified beyond the pin being valid.