mm in a Docker Sandbox — kits v3
The same two kits as ../docker-sbx, rewritten for the kit specification v3 (schemaVersion: "3"). docker-sbx/ (v2) is left untouched and keeps working: sbx still loads spec.yaml kits.
- mm-tui —
sbx runopens mm's window mode (mm -tui) on the workspace. - mm-acp —
sbx createonce, then an editor that speaks the Agent Client Protocol runssbx exec -i … mm -acp.
docker-sbx-v3/
├── publish.sh build + push the image, then build + push the kits — the one command to release
├── build.sh builds the template image, k33g/mm-sandbox:<version> (PUSH=1: multi-arch, pushed)
├── sync-kits.sh points the kits at one image: owner + version
├── check-kits.sh builds the kits locally (no push, no sbx) and checks them with kit-tck if present
├── push-kits.sh builds and pushes the kits with buildx: <owner>/sbx-kit-mm-tui, <owner>/sbx-kit-mm-acp
├── template/
│ ├── Dockerfile docker/sandbox-templates:shell + mm (built from this checkout) — same image as v2
│ ├── mm-tui entry point of the mm-tui kit: `mm -tui "$@"`
│ └── mm-acp-info entry point of the mm-acp kit: prints the editor wiring, opens a shell
└── kits/
├── mm-tui/
│ ├── mm-tui.yaml the descriptor: kind: workload, args, capabilities
│ └── mm-tui.dockerfile the content: FROM <image>:<tag>, ENV, ENTRYPOINT ["mm-tui"]
└── mm-acp/
├── mm-acp.yaml
└── mm-acp.dockerfile … ENTRYPOINT ["mm-acp-info"]
What changed from the v2 kits
v2 (docker-sbx/kits/*/spec.yaml) |
v3 (docker-sbx-v3/kits/*/) |
|
|---|---|---|
| Files | one spec.yaml |
<kit>.yaml (descriptor) + <kit>.dockerfile (content) |
| Kind | kind: sandbox |
kind: workload |
| Name | name: mm-tui |
none: a kit's identity is the reference it is consumed by |
| Image, entry point, env | sandbox.image, sandbox.entrypoint, environment.variables |
FROM, ENTRYPOINT, ENV in the Dockerfile — the descriptor restates nothing the image config carries |
| Network | permissions.network.allow |
capabilities: - type: com.docker.sandbox/network-policy@1 (runtime.allow) |
| Agent launch | implicit | capabilities: - type: com.docker.sandbox/sbx@1: the host runs the ENTRYPOINT under bash, as the image's user (agent) |
tag arg |
substituted into sandbox.image at create |
build-phase (buildArg: MM_TAG): baked in when the kit is built; also the kit's version and its provides: mm@<tag> |
config arg |
substituted into environment.variables |
create-phase (env: AGENT_CONFIG): exported to the container at sbx run / sbx create |
| Owner of the image | rewritten in sandbox.image |
its own build-phase arg, image (k33g/mm-sandbox) |
| Published as | sbx kit push → k33g/mm-tui, k33g/mm-acp |
docker buildx build --push → k33g/sbx-kit-mm-tui, k33g/sbx-kit-mm-acp (an ordinary multi-arch image, with SBOM and provenance) |
The repositories differ on purpose: pushing a v3 kit to k33g/mm-tui:<version> would replace the v2 kit published under that tag. sbx-kit-<name> is the naming Docker's own kits use.
Two things behave differently
The workspace is /home/agent/workspace. The template's base image declares that WORKDIR, and sbx@1 requires the host to mount the workspace at the image's working directory when it is absolute. A relative configuration path (config=agent.dmr.yaml) works as before. An absolute host path in AGENT_CONFIG (/Users/…/agent.dmr.yaml) does not: use the path relative to the workspace, or /home/agent/workspace/…. (Stated by the specification; not yet observed with sbx.)
The template image must be on a registry to run the kits from source. A v3 kit is built on top of the template (FROM k33g/mm-sandbox:<tag>), and sbx run ./docker-sbx-v3/kits/… builds it in sbx's builder sandbox, whose own Docker engine pulls that image from the registry. --pull never and sbx template load no longer help. Push the image (PUSH=1 ./docker-sbx-v3/build.sh) before running a kit from source, or check the kits without sbx with check-kits.sh.
0. Use the published kits (no build)
Once publish.sh has run for a version:
sbx kit inspect k33g/sbx-kit-mm-tui:0.2.1 # look before you run
cd /path/to/your/project
sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
sbx run k33g/sbx-kit-mm-tui:0.2.1 . --kit-arg config=agent.dmr.yaml
What follows -- is mm's own command line. Without it, mm reads the config argument, then ./agent.yaml in the workspace, then its built-in defaults.
From an editor, create the sandbox once, from the project the editor will open:
cd /path/to/your/project
sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
then register it — in Zed's settings.json:
{
"agent_servers": {
"mini-me (sandbox)": {
"type": "custom",
"command": "sbx",
"args": ["exec", "-i", "mm-acp", "mm", "-acp"]
}
}
}
Kit arguments. On a published kit only config can be set: image and tag are build-phase and were fixed when the kit was built, so a published kit always names the image it was built on. To use another mm version, take the kit of that version.
--kit-arg |
Default | Phase | Effect |
|---|---|---|---|
config=<path> |
empty | create | The file mm reads (its AGENT_CONFIG): relative to the workspace, or absolute inside the sandbox. Empty: ./agent.yaml, then the built-in defaults. |
tag=<version> |
mm's version (0.2.1) |
build | Which <image>:<tag> the kit is built FROM; also the kit's version. No v. |
image=<repo> |
k33g/mm-sandbox |
build | Which repository the kit is built FROM. |
1. Build the template
From the repository root:
./docker-sbx-v3/build.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, local store
PUSH=1 ./docker-sbx-v3/build.sh # multi-arch, pushed — needed before running a kit from source
Same image, same rules as v2's build.sh; it then rewrites the kits' image and tag defaults (sync-kits.sh), so the kits always name the image just built.
2. Check the kits without sbx
./docker-sbx-v3/check-kits.sh # both kits
./docker-sbx-v3/check-kits.sh mm-tui # one
Each kit is built with docker buildx build -f <kit>.yaml: the descriptor's first line, # syntax=docker/sandbox-kit:3, makes BuildKit pull the kit frontend, which validates the descriptor (unknown keys and arg patterns included), builds the companion Dockerfile and writes the published form to tmp/kits-v3/<kit>/. With kit-tck on the PATH (or KIT_TCK=/path/to/kit-tck), the result is also checked against the specification:
git clone https://github.com/docker/sandbox-kit-spec && cd sandbox-kit-spec
go build -o ~/.local/bin/kit-tck ./cmd/kit-tck
3. Run the kits from source
With the template pushed (section 1):
cd /path/to/your/project
sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml
sbx recognizes a v3 kit directory by its single *.yaml declaring schemaVersion: "3" (and no spec.yaml), builds it in its builder sandbox (sbx kit builder status), and caches the result by the directory's content. From source, the build-phase args can be set too: --kit-arg tag=0.2.2.
4. Publishing a version
export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner
export DOCKER_PAT=dckr_pat_… # an access token with read/write scope
./docker-sbx-v3/publish.sh # TAG from release.env: k33g/mm-sandbox:0.2.1, k33g/sbx-kit-mm-tui:0.2.1, k33g/sbx-kit-mm-acp:0.2.1
It is two steps you can also run alone:
PUSH=1 ./docker-sbx-v3/build.sh v0.2.1 # the image, multi-arch, pushed
./docker-sbx-v3/push-kits.sh v0.2.1 # the kits: buildx build --push, linux/amd64 + linux/arm64
push-kits.sh refuses to start when the image is not on the registry yet, runs sync-kits.sh, then builds each kit with the mm-sandbox-builder buildx instance (created by build.sh if needed) with SBOM and provenance attestations, and validates the pushed kits with kit-tck when it is available. No sbx is needed to publish. IMAGE_OWNER, REGISTRY, KIT_PREFIX and PLATFORMS override the defaults. The descriptors end up naming the new version — commit them.
The model server stays on the host
Unchanged from v2: inside a sandbox localhost is the sandbox itself, and Docker Model Runner or llama-server are reached through host.docker.internal. Both kits allow ports 12434 (Docker Model Runner) and 8080 (llama-server) on the host. Another port: sbx policy allow network host.docker.internal:<port>.
Status
Checked here: both kits build with the docker/sandbox-kit:3 frontend (3.0.0-m.6), single- and multi-arch with attestations, and pass kit-tck validate (18/18); the published config is User: agent, Entrypoint: [mm-tui] (or [mm-acp-info]), no Cmd, WorkingDir: /home/agent/workspace. Not yet checked: running them with sbx (sbx run, sbx create, sbx exec -i … mm -acp), and pushing to Docker Hub. The kit specification itself is still marked experimental.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
|