diff --git a/bot_bottle/contrib/claude/Dockerfile b/bot_bottle/contrib/claude/Dockerfile index 4834dd3..4c30481 100644 --- a/bot_bottle/contrib/claude/Dockerfile +++ b/bot_bottle/contrib/claude/Dockerfile @@ -10,7 +10,7 @@ # Current Node LTS; slim variant keeps the image small while still # providing apt-get for any future additions. -FROM node:22-slim +FROM node:22-trixie-slim # Install runtime system deps. claude-code shells out to git for several # features (status checks, commits, PR creation) — without git in the @@ -21,7 +21,14 @@ FROM node:22-slim # to it) works against egress's bumped TLS without the agent needing # local DNS. RUN apt-get update \ - && apt-get install -y --no-install-recommends git ca-certificates curl ripgrep iproute2 dnsutils \ + && apt-get install -y --no-install-recommends \ + git \ + ca-certificates \ + curl \ + podman \ + ripgrep \ + iproute2 \ + dnsutils \ && rm -rf /var/lib/apt/lists/* # App-specific deps. Python isn't required by claude-code itself diff --git a/bot_bottle/contrib/codex/Dockerfile b/bot_bottle/contrib/codex/Dockerfile index c966b8d..36d9507 100644 --- a/bot_bottle/contrib/codex/Dockerfile +++ b/bot_bottle/contrib/codex/Dockerfile @@ -3,10 +3,16 @@ # Mirrors the default Claude image shape: Node LTS, git/network tooling, # non-root node user, and the provider CLI installed for that user. -FROM node:22-slim +FROM node:22-trixie-slim RUN apt-get update \ - && apt-get install -y --no-install-recommends git ca-certificates curl procps ripgrep \ + && apt-get install -y --no-install-recommends \ + git \ + ca-certificates \ + curl \ + podman \ + procps \ + ripgrep \ && rm -rf /var/lib/apt/lists/* # App-specific deps. Python isn't required by codex itself diff --git a/bot_bottle/contrib/pi/Dockerfile b/bot_bottle/contrib/pi/Dockerfile index 20a5f29..9036c92 100644 --- a/bot_bottle/contrib/pi/Dockerfile +++ b/bot_bottle/contrib/pi/Dockerfile @@ -2,7 +2,7 @@ # # Node LTS, git/network tooling, and the Pi coding-agent CLI installed globally. -FROM node:22-slim +FROM node:22-trixie-slim RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -10,6 +10,7 @@ RUN apt-get update \ ca-certificates \ curl \ fd-find \ + podman \ ripgrep \ && ln -s /usr/bin/fdfind /usr/local/bin/fd \ && rm -rf /var/lib/apt/lists/* diff --git a/docs/prds/prd-new-modernize-built-in-agent-images.md b/docs/prds/prd-new-modernize-built-in-agent-images.md new file mode 100644 index 0000000..4a5d3fd --- /dev/null +++ b/docs/prds/prd-new-modernize-built-in-agent-images.md @@ -0,0 +1,43 @@ +# PRD prd-new: Modernize built-in agent images + +- **Status:** Draft +- **Author:** Codex +- **Created:** 2026-07-21 +- **Issue:** #451 + +## Summary + +Keep every built-in agent provider on Debian's current stable release and make +Podman available inside each image. This gives agents a consistent, modern +userspace and an OCI container tool without requiring per-project setup. + +## Problem + +The Claude, Codex, and Pi images inherit the generic `node:22-slim` tag. That +tag does not state which Debian release the project supports and currently +leaves the images on the older Bookworm release. None of the built-in images +installs Podman, so tasks that need to inspect or build OCI images must first +modify the bottle or cannot run at all. + +## Goals / success criteria + +- Every Dockerfile under `bot_bottle/contrib/*/Dockerfile` explicitly inherits + `node:22-trixie-slim`, based on Debian 13 (the current stable release). +- Every built-in agent image installs Podman from Debian stable. +- A shared test enforces both requirements for current and future built-in + providers. + +## Non-goals + +- Configuring privileged or nested-container execution for bottles. +- Pinning Podman outside Debian's stable package repository. +- Changing the Node.js or agent CLI release policy. + +## Design + +Use the explicit `node:22-trixie-slim` base rather than the floating `slim` +variant. Install the `podman` package with each image's existing `apt-get` +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 +keeps the images stdlib/distribution-first and avoids adding a third-party +package repository. diff --git a/tests/unit/test_builtin_agent_images.py b/tests/unit/test_builtin_agent_images.py new file mode 100644 index 0000000..45c5024 --- /dev/null +++ b/tests/unit/test_builtin_agent_images.py @@ -0,0 +1,34 @@ +"""Unit contracts shared by all built-in agent images.""" + +from __future__ import annotations + +import re +import unittest +from pathlib import Path + + +_CONTRIB_DIR = Path(__file__).resolve().parents[2] / "bot_bottle/contrib" +_AGENT_DOCKERFILES = tuple(sorted(_CONTRIB_DIR.glob("*/Dockerfile"))) + + +class TestBuiltinAgentImages(unittest.TestCase): + def test_all_use_debian_trixie_stable(self): + self.assertTrue(_AGENT_DOCKERFILES) + for dockerfile in _AGENT_DOCKERFILES: + with self.subTest(provider=dockerfile.parent.name): + self.assertRegex( + dockerfile.read_text(), + r"(?m)^FROM node:22-trixie-slim\s*$", + ) + + def test_all_install_podman(self): + for dockerfile in _AGENT_DOCKERFILES: + with self.subTest(provider=dockerfile.parent.name): + self.assertRegex( + dockerfile.read_text(), + re.compile(r"(?m)^\s*podman(?:\s|\\|$)"), + ) + + +if __name__ == "__main__": + unittest.main()