refactor(agent-images): use explicit Debian base
tracker-policy-pr / check-pr (pull_request) Successful in 13s
test / integration-docker (pull_request) Successful in 36s
test / unit (pull_request) Successful in 43s
lint / lint (push) Successful in 50s
test / integration-firecracker (pull_request) Failing after 7m18s
test / coverage (pull_request) Has been skipped
test / publish-infra (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Successful in 13s
test / integration-docker (pull_request) Successful in 36s
test / unit (pull_request) Successful in 43s
lint / lint (push) Successful in 50s
test / integration-firecracker (pull_request) Failing after 7m18s
test / coverage (pull_request) Has been skipped
test / publish-infra (pull_request) Has been skipped
This commit is contained in:
@@ -8,15 +8,15 @@
|
|||||||
# Layer ordering is deliberate: the npm install lives in its own layer so
|
# Layer ordering is deliberate: the npm install lives in its own layer so
|
||||||
# changes to the rest of the repo (or to the CMD) don't bust it.
|
# changes to the rest of the repo (or to the CMD) don't bust it.
|
||||||
|
|
||||||
# Current Node LTS; slim variant keeps the image small while still
|
# Debian stable is the supported userspace. The provider's Node.js runtime is
|
||||||
# providing apt-get for any future additions.
|
# installed explicitly below rather than inherited from a language image.
|
||||||
FROM node:22-trixie-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
# Install runtime system deps. claude-code shells out to git for several
|
# Install runtime system deps. claude-code shells out to git for several
|
||||||
# features (status checks, commits, PR creation) — without git in the
|
# features (status checks, commits, PR creation) — without git in the
|
||||||
# image, those features fail in surprising ways once the user does any
|
# image, those features fail in surprising ways once the user does any
|
||||||
# real work. ca-certificates is already in the slim base; listed for
|
# real work. ca-certificates is installed explicitly for TLS clients. curl is
|
||||||
# clarity in case the base ever drops it. curl is here so any
|
# here so any
|
||||||
# HTTPS_PROXY-aware tool (curl itself, plus anything that shells out
|
# HTTPS_PROXY-aware tool (curl itself, plus anything that shells out
|
||||||
# to it) works against egress's bumped TLS without the agent needing
|
# to it) works against egress's bumped TLS without the agent needing
|
||||||
# local DNS.
|
# local DNS.
|
||||||
@@ -30,8 +30,13 @@ RUN apt-get update \
|
|||||||
ripgrep \
|
ripgrep \
|
||||||
iproute2 \
|
iproute2 \
|
||||||
dnsutils \
|
dnsutils \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN groupadd --gid 1000 node \
|
||||||
|
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node
|
||||||
|
|
||||||
# App-specific deps. Python isn't required by claude-code itself
|
# App-specific deps. Python isn't required by claude-code itself
|
||||||
# (claude-code is a Node CLI), but is convenient for the agent to
|
# (claude-code is a Node CLI), but is convenient for the agent to
|
||||||
# shell out to for ad-hoc scripts. Kept on its own layer so it can
|
# shell out to for ad-hoc scripts. Kept on its own layer so it can
|
||||||
@@ -52,9 +57,8 @@ RUN npm install -g --no-fund --no-audit @anthropic-ai/claude-code@2.1.172 \
|
|||||||
# suppress bot-bottle's git-gate insteadOf rules.
|
# suppress bot-bottle's git-gate insteadOf rules.
|
||||||
RUN install -d -o node -g node -m 755 /home/node/.config /home/node/.config/git
|
RUN install -d -o node -g node -m 755 /home/node/.config /home/node/.config/git
|
||||||
|
|
||||||
# Run as a non-root user. The node image already provides a `node` user
|
# Run as the explicitly-created non-root user. Claude Code writes its session
|
||||||
# (uid 1000) with a home directory, which is where claude-code will write
|
# state under this user's home directory.
|
||||||
# its session state.
|
|
||||||
USER node
|
USER node
|
||||||
WORKDIR /home/node
|
WORKDIR /home/node
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# bot-bottle Codex provider image.
|
# bot-bottle Codex provider image.
|
||||||
#
|
#
|
||||||
# Mirrors the default Claude image shape: Node LTS, git/network tooling,
|
# Mirrors the default Claude image shape: Debian stable, git/network tooling,
|
||||||
# non-root node user, and the provider CLI installed for that user.
|
# a non-root runtime user, and the provider CLI installed for that user.
|
||||||
|
|
||||||
FROM node:22-trixie-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
@@ -16,8 +16,11 @@ RUN apt-get update \
|
|||||||
ripgrep \
|
ripgrep \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# App-specific deps. Python isn't required by codex itself
|
RUN groupadd --gid 1000 node \
|
||||||
# (codex is a Node CLI), but is convenient for the agent to shell
|
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node
|
||||||
|
|
||||||
|
# App-specific deps. Python isn't required by Codex itself, but is convenient
|
||||||
|
# for the agent to shell
|
||||||
# out to for ad-hoc scripts. Kept on its own layer so it can be
|
# out to for ad-hoc scripts. Kept on its own layer so it can be
|
||||||
# moved to a downstream image if the base ever needs to shrink.
|
# moved to a downstream image if the base ever needs to shrink.
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
@@ -32,8 +35,8 @@ WORKDIR /home/node
|
|||||||
ENV PATH="/home/node/.local/bin:${PATH}"
|
ENV PATH="/home/node/.local/bin:${PATH}"
|
||||||
|
|
||||||
# Remote-control support requires the standalone Codex install layout
|
# Remote-control support requires the standalone Codex install layout
|
||||||
# under ~/.codex/packages/standalone/current. The npm package can run
|
# under ~/.codex/packages/standalone/current. Remote-control commands expect
|
||||||
# the TUI, but remote-control commands expect this installer-owned path.
|
# this installer-owned path.
|
||||||
RUN mkdir -p /home/node/.codex \
|
RUN mkdir -p /home/node/.codex \
|
||||||
&& curl -fsSL https://chatgpt.com/codex/install.sh | sh
|
&& curl -fsSL https://chatgpt.com/codex/install.sh | sh
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# bot-bottle Pi provider image.
|
# bot-bottle Pi provider image.
|
||||||
#
|
#
|
||||||
# Node LTS, git/network tooling, and the Pi coding-agent CLI installed globally.
|
# Debian stable, git/network tooling, and the Pi coding-agent CLI.
|
||||||
|
|
||||||
FROM node:22-trixie-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
@@ -13,9 +13,14 @@ RUN apt-get update \
|
|||||||
openssh-client \
|
openssh-client \
|
||||||
podman \
|
podman \
|
||||||
ripgrep \
|
ripgrep \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
|
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN groupadd --gid 1000 node \
|
||||||
|
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends python3 python3-pip python3-venv \
|
&& apt-get install -y --no-install-recommends python3 python3-pip python3-venv \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
@@ -13,16 +13,18 @@ userspace and an OCI container tool without requiring per-project setup.
|
|||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
The Claude, Codex, and Pi images inherit the generic `node:22-slim` tag. That
|
The Claude, Codex, and Pi images inherited the generic `node:22-slim` tag. That
|
||||||
tag does not state which Debian release the project supports and currently
|
tag did not make Debian the explicit supported base and left the images on the
|
||||||
leaves the images on the older Bookworm release. None of the built-in images
|
older Bookworm release. None of the built-in images installed Podman, so tasks
|
||||||
installs Podman, so tasks that need to inspect or build OCI images must first
|
that need to inspect or build OCI images first had to modify the bottle or
|
||||||
modify the bottle or cannot run at all.
|
could not run at all.
|
||||||
|
|
||||||
## Goals / success criteria
|
## Goals / success criteria
|
||||||
|
|
||||||
- Every Dockerfile under `bot_bottle/contrib/*/Dockerfile` explicitly inherits
|
- Every Dockerfile under `bot_bottle/contrib/*/Dockerfile` explicitly inherits
|
||||||
`node:22-trixie-slim`, based on Debian 13 (the current stable release).
|
`debian:trixie-slim`, Debian 13 (the current stable release).
|
||||||
|
- Every image explicitly creates the non-root `node` runtime user with UID and
|
||||||
|
GID 1000 instead of relying on a language image to provide it.
|
||||||
- Every built-in agent image installs Podman from Debian stable.
|
- Every built-in agent image installs Podman from Debian stable.
|
||||||
- Every built-in agent image retains an SSH client for Git-over-SSH workflows.
|
- Every built-in agent image retains an SSH client for Git-over-SSH workflows.
|
||||||
- The non-root agent user owns a traversable XDG Git configuration directory,
|
- The non-root agent user owns a traversable XDG Git configuration directory,
|
||||||
@@ -39,9 +41,10 @@ modify the bottle or cannot run at all.
|
|||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
Use the explicit `node:22-trixie-slim` base rather than the floating `slim`
|
Use the explicit `debian:trixie-slim` base. Install Node.js and npm from Debian
|
||||||
variant. Install the `podman` package with each image's existing `apt-get`
|
stable where a provider needs them, and create the common `node` runtime user
|
||||||
|
explicitly. Install the `podman` package with each image's existing `apt-get`
|
||||||
dependency layer, so package metadata and caches are still removed in the same
|
dependency layer, so package metadata and caches are still removed in the same
|
||||||
layer. Treat Debian stable as the Podman stability and update channel; this
|
layer. Treat Debian stable as the Node.js and Podman stability and update
|
||||||
keeps the images stdlib/distribution-first and avoids adding a third-party
|
channel; this keeps the images distribution-first and avoids adding a
|
||||||
package repository.
|
third-party package repository.
|
||||||
|
|||||||
@@ -18,7 +18,18 @@ class TestBuiltinAgentImages(unittest.TestCase):
|
|||||||
with self.subTest(provider=dockerfile.parent.name):
|
with self.subTest(provider=dockerfile.parent.name):
|
||||||
self.assertRegex(
|
self.assertRegex(
|
||||||
dockerfile.read_text(),
|
dockerfile.read_text(),
|
||||||
r"(?m)^FROM node:22-trixie-slim\s*$",
|
r"(?m)^FROM debian:trixie-slim\s*$",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_all_create_node_runtime_user(self):
|
||||||
|
for dockerfile in _AGENT_DOCKERFILES:
|
||||||
|
with self.subTest(provider=dockerfile.parent.name):
|
||||||
|
dockerfile_text = dockerfile.read_text()
|
||||||
|
self.assertIn("groupadd --gid 1000 node", dockerfile_text)
|
||||||
|
self.assertIn(
|
||||||
|
"useradd --uid 1000 --gid node --shell /bin/bash "
|
||||||
|
"--create-home node",
|
||||||
|
dockerfile_text,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_all_install_podman(self):
|
def test_all_install_podman(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user