docs(sandbox): publish the installed sandbox as a containerDisk - #3155
Merged
Conversation
Turn the hand-built sandbox into an OCI containerDisk, push it to GHCR, and boot it locally and on Fleet, so the GUI install never has to be repeated — least of all on Fleet. Covers what a containerDisk is, never signing in before exporting and the three places a credential survives if you do, creating the instance and fetching Java without a Microsoft account, the sb.stop() trap, qemu-img convert, the two-line Dockerfile, --provenance=false --sbom=false, GHCR being private on first push, and the os_type override that keeps a Windows disk off SeaBIOS. Verified end to end as ghcr.io/trycua/minecraft-agent:1.20.1: export 8m44s for 7,697,072,128 bytes, build and push 6m28s as a plain manifest, anonymous pull 200 with no credentials, local boot with the game files intact, and a Fleet boot READY in 157 s — the first confirmation that a custom Windows containerDisk on a public non-ECR registry runs there. Retrying a BindDeadlineExceeded boot under the same name returns 403 on update template, because both branches of the gateway image policy are guarded by input.method != "PATCH": a template can be created but never updated. The retry needs a new name. tunnel.forward() is also not available on a pool-claim sandbox, which carries the base FleetTransport. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
r33drichards
force-pushed
the
mc-containerdisk
branch
from
August 13, 2026 21:15
5a52021 to
ed928bf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3131. That PR merged before this section was finished, so these commits were left on the branch after it closed.
Adds Publish the installed sandbox as a containerDisk: turn the sandbox you just built by hand into an OCI image, push it to GHCR, and boot it locally and on Fleet — so nobody has to repeat the GUI install, least of all on Fleet.
Covered
/disk/disk.img, which despite the name is qcow2)sb.stop()trap that deletes the session diskqemu-img convert -O qcow2 -c, the two-line Dockerfile, and--provenance=false --sbom=falsewrite:packagesos_typeoverride, and why a Windows containerDisk otherwise boots SeaBIOS against a GPT diskVerified end to end while writing it
Published as
ghcr.io/trycua/minecraft-agent:1.20.1(repo created for this) and booted from it:unknown/unknownchildrenjavaw.exe, noaccounts.jsonThat Fleet boot is the first end-to-end confirmation that a custom Windows containerDisk on a public non-ECR registry runs there. It needs cua-sandbox 0.3.2 (#3148); before that the gateway refused any non-allowlisted image.
Two corrections in the last commit, both from running it
The retry advice was wrong. The section said to retry a
BindDeadlineExceededboot. Doing that returns403 k8s request is not allowedonupdate template— both branches ofpool_admission.regoare guarded byinput.method != "PATCH", so a template can be created but never updated, and reusing the name makes the SDK patch it. The retry needs a new name. Sequence measured: cold attempt hit the 300 s deadline → same name returned 403 → fresh name reached READY in 157 s.tunnel.forward(3000)does not work on every Fleet path. A sandbox from a pool claim carries the baseFleetTransport, which does not implement port forwarding (pool.py:161); only a directly-created sandbox carriesFleetCloudTransport. The error names the transport, not the cause.Not verified
java-runtime-gammais untested.READYdoes imply the readiness wait passed.Credential hygiene
The first export was discarded. It passed every filesystem check —
accounts.jsongone, in-guestfindstrclean, Prism showing an empty account wizard — and the raw image still had 47 hits for the refresh-token prefix and profile name, inpagefile.sys, in file slack past a log's valid-data length, and in unallocated clusters the zero-fill missed. The published image was rebuilt without ever signing in. Scanned before publishing: refresh-token prefix 0, profile name 0. The 86 JWT headers present decode to RFC 7515 example data (http://example.com/is_root":true}), and the pristine base image already carries 58 of them.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
🤖 Generated with Claude Code