diff --git a/apps/workers/coder-acp-claude-code/Dockerfile b/apps/workers/coder-acp-claude-code/Dockerfile index e888312e..6c0a15bb 100644 --- a/apps/workers/coder-acp-claude-code/Dockerfile +++ b/apps/workers/coder-acp-claude-code/Dockerfile @@ -8,7 +8,10 @@ ENV npm_config_registry=${NPM_CONFIG_REGISTRY} \ # which some private registry proxies don't serve; fall back to a pinned global # install (honors npm_config_registry) so restricted networks can still build. RUN corepack enable && (corepack prepare pnpm@10.29.1 --activate || npm install -g pnpm@10.29.1 --force) -# Install system tools for coding agents: Python, uv, git, PowerShell, Go, .NET, Rust, Java, Maven, Gradle +# Pinned like every other system tool below so image builds stay reproducible. +ARG GH_VERSION=2.100.0 + +# Install system tools for coding agents: Python, uv, git, GitHub CLI, PowerShell, Go, .NET, Rust, Java, Maven, Gradle RUN apt-get update && apt-get install -y \ python3 \ python3-pip \ @@ -64,9 +67,18 @@ RUN apt-get update && apt-get install -y \ && rm /tmp/gradle.zip \ && chmod +x /opt/gradle/gradle-8.12/bin/gradle \ && ln -s /opt/gradle/gradle-8.12/bin/gradle /usr/local/bin/gradle \ + && curl -fsSL -o /tmp/gh.tar.gz \ + "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${ARCH}.tar.gz" \ + && tar -xzf /tmp/gh.tar.gz -C /tmp \ + && mv "/tmp/gh_${GH_VERSION}_linux_${ARCH}/bin/gh" /usr/local/bin/gh \ + && chmod +x /usr/local/bin/gh \ + && rm -rf /tmp/gh.tar.gz "/tmp/gh_${GH_VERSION}_linux_${ARCH}" \ + && gh --version \ && rm -rf /var/lib/apt/lists/* ENV PATH="/root/.cargo/bin:/root/.local/bin:$PATH" +# Surfaced at runtime so the worker can report the toolchain it actually shipped. +ENV GH_VERSION=${GH_VERSION} # Disable Claude Code "policy skills" (auto-loaded, Anthropic-managed Agent Skills). # As of claude-agent-acp 0.52.0 / claude-agent-sdk 0.3.191 the bundled agent auto-invokes diff --git a/apps/workers/coder-acp-copilot-windows/Dockerfile.base b/apps/workers/coder-acp-copilot-windows/Dockerfile.base index 441af47d..881f5554 100644 --- a/apps/workers/coder-acp-copilot-windows/Dockerfile.base +++ b/apps/workers/coder-acp-copilot-windows/Dockerfile.base @@ -20,6 +20,12 @@ RUN Invoke-WebRequest -Uri "https://nodejs.org/dist/v${env:NODE_VERSION}/node-v$ # Install git via Chocolatey RUN choco install -y git +# Install GitHub CLI via Chocolatey (pinned to match the Linux worker images) +# No version check here: the chocolatey shim directory only joins PATH via the +# ENV below, so `gh` is not yet invokable at this layer (same as git above). +ARG GH_VERSION=2.100.0 +RUN choco install -y gh --version=$env:GH_VERSION + # Install pnpm as a standalone executable RUN New-Item -ItemType Directory -Force -Path C:\tools | Out-Null; \ Invoke-WebRequest -Uri 'https://github.com/pnpm/pnpm/releases/download/v10.29.1/pnpm-win-x64.exe' \ diff --git a/apps/workers/coder-acp-copilot/Dockerfile b/apps/workers/coder-acp-copilot/Dockerfile index a34e9ccd..1d184092 100644 --- a/apps/workers/coder-acp-copilot/Dockerfile +++ b/apps/workers/coder-acp-copilot/Dockerfile @@ -10,7 +10,10 @@ ENV npm_config_registry=${NPM_CONFIG_REGISTRY} \ # which some private registry proxies don't serve; fall back to a pinned global # install (honors npm_config_registry) so restricted networks can still build. RUN corepack enable && (corepack prepare pnpm@10.29.1 --activate || npm install -g pnpm@10.29.1 --force) -# Install system tools for coding agents: Python, uv, git, PowerShell, Go, .NET, Rust, Java, Maven, Gradle +# Pinned like every other system tool below so image builds stay reproducible. +ARG GH_VERSION=2.100.0 + +# Install system tools for coding agents: Python, uv, git, GitHub CLI, PowerShell, Go, .NET, Rust, Java, Maven, Gradle RUN apt-get update && apt-get install -y \ python3 \ python3-pip \ @@ -68,9 +71,18 @@ RUN apt-get update && apt-get install -y \ && rm /tmp/gradle.zip \ && chmod +x /opt/gradle/gradle-8.12/bin/gradle \ && ln -s /opt/gradle/gradle-8.12/bin/gradle /usr/local/bin/gradle \ + && curl -fsSL -o /tmp/gh.tar.gz \ + "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${ARCH}.tar.gz" \ + && tar -xzf /tmp/gh.tar.gz -C /tmp \ + && mv "/tmp/gh_${GH_VERSION}_linux_${ARCH}/bin/gh" /usr/local/bin/gh \ + && chmod +x /usr/local/bin/gh \ + && rm -rf /tmp/gh.tar.gz "/tmp/gh_${GH_VERSION}_linux_${ARCH}" \ + && gh --version \ && rm -rf /var/lib/apt/lists/* ENV PATH="/root/.cargo/bin:/root/.local/bin:$PATH" +# Surfaced at runtime so the worker can report the toolchain it actually shipped. +ENV GH_VERSION=${GH_VERSION} # --- Builder stage: compile TypeScript --- FROM base AS builder diff --git a/docker-compose.yml b/docker-compose.yml index fac8bcd6..b63fbd86 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -607,6 +607,15 @@ services: profiles: [claude-code] group_add: - "${DOCKER_GID:-0}" # Docker socket GID (0 for macOS/Docker Desktop, set DOCKER_GID for Linux) + security_opt: + # The right GID is necessary but not sufficient when the daemon host + # enforces SELinux (a podman machine always does; RHEL/Fedora Docker Engine + # can): container_t may not open a var_run_t socket, so the mounted socket + # stays unusable and the agent cannot run containers at all. Ignored on + # hosts without SELinux, such as Docker Desktop. + # label=type:container_runtime_t also works and keeps confinement, but it + # requires container-selinux to provide that type. + - label=disable environment: <<: *worker-env WORKER_NAME: coder-acp-claude-code @@ -713,6 +722,15 @@ services: profiles: [copilot] group_add: - "${DOCKER_GID:-0}" # Docker socket GID (0 for macOS/Docker Desktop, set DOCKER_GID for Linux) + security_opt: + # The right GID is necessary but not sufficient when the daemon host + # enforces SELinux (a podman machine always does; RHEL/Fedora Docker Engine + # can): container_t may not open a var_run_t socket, so the mounted socket + # stays unusable and the agent cannot run containers at all. Ignored on + # hosts without SELinux, such as Docker Desktop. + # label=type:container_runtime_t also works and keeps confinement, but it + # requires container-selinux to provide that type. + - label=disable environment: <<: *worker-env WORKER_NAME: coder-acp-copilot