feat(smolmachines): build agent image from repo Dockerfile (PRD 0023 chunk 4c) #71
Reference in New Issue
Block a user
Delete Branch "prd-0023-chunk-4c-agent-image"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
smolvm pack createonly takes OCI registry refs (tested: rejectsdocker-daemon://,oci-layout://,docker-archive:tarballs, and every other transport — crane treats anything with a scheme prefix as a registry hostname)..smolmachinewe now bring up an ephemeralregistry:2.8.3on127.0.0.1:<random>,docker tag+docker pushinto it, runsmolvm pack create --image localhost:<port>/..., and tear down the registry. Loopback-only bind, no LAN exposure..smolmachineartifacts are cached under~/.cache/claude-bottle/smolmachines/keyed by the docker image ID (first 16 hex chars of the sha256), so a Dockerfile change picks up a new image ID and re-runs the pipeline; unchanged rebuilds skip it entirely.docker tag/docker push/docker image inspecthelpers inbackend/docker/util.py. Addsbackend/smolmachines/local_registry.pyfor the ephemeral-registry context manager (pinned registry:2.8.3 by digest).PRD 0023 is updated with the registry-hop rationale.
Chunk 4d (
provision_ca+provision_git+provision_supervise) is the follow-up — those need this agent image to be in place soupdate-ca-certificates,git, andclaude mcp addexist inside the guest.@@ -0,0 +30,4 @@# pipelock image pin in claude_bottle/backend/docker/pipelock.py.REGISTRY_IMAGE = os.environ.get("CLAUDE_BOTTLE_REGISTRY_IMAGE","registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373",How much attack surface does the env var and this registry download introduce (and the local registry step in general)
@@ -0,0 +30,4 @@# pipelock image pin in claude_bottle/backend/docker/pipelock.py.REGISTRY_IMAGE = os.environ.get("CLAUDE_BOTTLE_REGISTRY_IMAGE","registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373",Small, mostly equivalent to the docker dependencies the project already has.
The pulled image —
registry:2.8.3pinned by digest (sha256:a3d8aaa6...). Distribution's open-source registry from Docker Inc., the upstream of every docker daemon'sdocker push; CVE history is mostly DoS, no RCE. Pinning means the bytes are immutable — once the digest is in the source tree, every machine that runs this verifies against it. Same trust model as theghcr.io/luckypipewrench/pipelock@sha256:3b1a3941...pin inbackend/docker/pipelock.py.The running registry container — bound to
127.0.0.1::5000(loopback only, no LAN exposure), lives ~5-10s during onepreparecall, force-removed infinally. While alive it's reachable by other processes on the host running as the same uid — but those processes are already past whatever sandbox the project provides (this is host-side bringup, before the bottle exists). They could read the pushed image bytes, but those bytes are the public Dockerfile-built image — no secrets baked in.The env var override — same pattern as
CLAUDE_BOTTLE_PIPELOCK_IMAGE,CLAUDE_BOTTLE_EGRESS_PORT, etc. An attacker who can set arbitrary env vars in the shell that runscli.pycan already substitutePATH,DOCKER_HOST,LD_PRELOAD, etc. — way nastier vectors than swapping the registry image. It exists for developer override (testing against a different registry version); shouldn't appear in production wrapping scripts.What it doesn't add — no new network surface (loopback only), no new persistent state (container is
--rm), no secrets in flight (the pushed image is just the agent Dockerfile output), no new privileged ops (registry runs as itsregistryuser inside its container).The one thing worth flagging: this puts a docker dependency in the smolmachines prepare path that wasn't there before (the docker backend ships with
dockeras a hard requirement; smolmachines previously only needed it for the sidecar bundle, now also for the agent-image build). Worth a README note for the v1 macOS-only scope.