feat(smolmachines): build agent image from repo Dockerfile (PRD 0023 chunk 4c)
Replaces the alpine:latest placeholder with a real claude-bottle agent image, converted into a .smolmachine artifact via an ephemeral local OCI registry. Why the registry hop: smolvm pack create only accepts OCI registry refs. Empirically it rejects docker-daemon://, oci-layout://, docker-archive: tarballs, and every other transport tested — the crane backend treats anything with a scheme prefix as a registry hostname. To convert a locally-built docker image into a .smolmachine we have to push it somewhere smolvm can pull from. Smallest path: bring up registry:2.8.3 bound to 127.0.0.1:<random>, docker tag + docker push into it, smolvm pack create --image localhost:<port>/claude-bottle:<id>, tear down the registry. The .smolmachine is 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 invalidates the cache. Unchanged rebuilds skip the whole build → registry → pack pipeline. This puts `docker build` in smolmachines prepare (the docker backend defers it to launch). Necessary because pack_create needs the image ID to derive the cache key, and prepare is the only hook ahead of launch that runs once per slug. Adds: - claude_bottle/backend/docker/util.py: image_id / tag / push helpers (thin docker CLI wrappers). - claude_bottle/backend/smolmachines/local_registry.py: ephemeral_registry() context manager; pins registry:2.8.3 by digest, binds 127.0.0.1::5000 (loopback-only), force-removes on exit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit was merged in pull request #71.
This commit is contained in:
@@ -393,10 +393,19 @@ Three changes vs. the Docker backend:
|
||||
2. Derive a per-bottle docker subnet from `sha256(slug) % 254`
|
||||
(skipping the docker-default 17): `192.168.X.0/24`. The bundle
|
||||
IP is always `192.168.X.2` (gateway is `.1`).
|
||||
3. Resolve the agent guest image: convert the existing
|
||||
`Dockerfile` into a `.smolmachine` artifact via
|
||||
`smolvm pack create --image <name> -o <stage>/agent.smolmachine`
|
||||
(idempotent, layer-cached).
|
||||
3. Resolve the agent guest image: `docker build` the existing
|
||||
`Dockerfile`, then convert the resulting image into a
|
||||
`.smolmachine` artifact. Empirically `smolvm pack create` only
|
||||
reads OCI registry refs — it rejects `docker-daemon://`,
|
||||
`oci-layout://`, `docker-archive:` tarballs, and every other
|
||||
transport tested. The conversion path is a registry hop: bring
|
||||
up an ephemeral `registry:2.8.3` container bound to
|
||||
`127.0.0.1:<random>`, `docker tag` + `docker push` into it,
|
||||
`smolvm pack create --image localhost:<port>/claude-bottle:<id>`,
|
||||
tear down the registry. The `.smolmachine` is cached under
|
||||
`~/.cache/claude-bottle/smolmachines/` keyed by the docker
|
||||
image ID, so Dockerfile changes invalidate the cache and
|
||||
unchanged rebuilds skip the whole pipeline.
|
||||
4. Render the per-bottle Smolfile to `stage_dir/smolfile.toml`
|
||||
using smolvm 0.8.0's schema:
|
||||
- `image` / `entrypoint` / `cmd` — bundled into the
|
||||
|
||||
Reference in New Issue
Block a user