mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #325] [CLOSED] feat(compose): add Docker Compose sandboxes #350
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#350
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/325
Author: @Primary33
Created: 9/29/2026
Status: ❌ Closed
Base:
main← Head:feat/sandbox-compose📝 Commits (1)
ac97300feat(compose): add Docker Compose sandboxes📊 Changes
60 files changed (+6544 additions, -261 deletions)
View changed files
📝
.github/workflows/release.yml(+10 -0)➕
compose-image/Dockerfile(+118 -0)➕
compose-image/test_e2e.py(+425 -0)📝
crates/aenv/src/client/sandboxes.rs(+106 -1)📝
crates/aenv/src/commands/build.rs(+246 -83)➕
crates/aenv/src/commands/compose.rs(+486 -0)➕
crates/aenv/src/commands/compose/runtime.rs(+520 -0)📝
crates/aenv/src/commands/mod.rs(+11 -0)📝
crates/aenv/src/commands/start.rs(+2 -10)📝
crates/aenv/src/main.rs(+3 -0)➕
crates/aenv/tests/compose_runtime.rs(+62 -0)📝
deploy/docker/Dockerfile.agentenv(+7 -0)📝
docs/src/SUMMARY.md(+1 -0)➕
docs/src/concepts/sandboxes/compose.md(+302 -0)📝
scripts/install.sh(+3 -0)📝
services/Makefile(+5 -0)📝
services/api/proto/scheduler.pb.go(+30 -9)📝
services/api/proto/scheduler.proto(+4 -0)➕
services/compose/cmd/main.go(+61 -0)➕
services/compose/cmd/main_test.go(+52 -0)...and 40 more files
📄 Description
What
Run multi-service Docker Compose projects inside one Firecracker sandbox, including remote Dockerfile builds that import service images directly into the node cache:
Terminal-Bench 4.0: all 11 Compose task environments passed, covering 38 services. Validation includes original environment builds, startup, configured health checks, and execution inside every task's
maincontainer. This is environment validation; agent solving and task scoring were not run.Why
Multi-service tasks need to build and start without a client-side Docker daemon or destination registry, while preserving independent writable service filesystems and AgentENV's existing pause, resume, fork, and snapshot behavior.
Related issue
Builds on the plain snapshotter introduced in #318.
Scope and non-goals
Supports Linux x86-64/KVM, 1–24 services, local Dockerfile contexts, build arguments/targets/no-cache, profiles, explicit environment interpolation, dependencies, health checks, named volumes, bridge networking, fixed TCP ports, shared service network namespaces, and
SYS_PTRACE.Runtime requests remain image-only. Scaling, host bind mounts, external files/resources, privileged containers, host networking/devices, arbitrary added capabilities, and UDP publishing remain unsupported.
--harborsupplies task build/keepalive defaults; a Harbor backend and benchmark agents/verifiers are outside this change.Design and behavior changes
POST /sandboxes-compose/plan. Planning runs on the server, has a 30-second budget, reads no client files, and allocates no builders or sandboxes. The Go planner is packaged with the server; build contexts are uploaded separately through the existing BuildKit tunnel.aenv build --composebuilds active services and atomically publishes the normalized Compose file after all builds succeed. Existing output files are rejected. Default builds import manifest digests into one node's cache;--image-repositoryoptionally distributes images through a registry.compose-image/Dockerfile./route.Compatibility and operations
compose.base_image; planning requirescompose.planner_binary. Only the server needs the planner. Default Compose builds require no destination registry; base-image pulls still use their configured sources.Validation
All validation ran on a dedicated Ubuntu 24.04 Linux x86-64/KVM test server, with non-root execution and isolated state/dependency directories. Normalized SHA-256 fingerprints for all 819 source files were checked against the final working tree.
Terminal-Bench 4.0 — 11/11 environments passed
Tested the unmodified
v4.0.0task checkout, commit452bf305c6daa62fc59061d22133a7cbc7c1572e, using the repository's existing environment harness:AENV_API_URL,AENV_API_KEY, andAENV_CLIpoint to the isolated test deployment. The default node-local image-import path was used, with no destination registry supplied to task builds.ctr-optimizationcumulative-layout-shiftfreight-dispatch-shiftheat-pump-warrantyintrastat-meldungkv-live-surgerylegacy-utility-triagelive-database-cutovermedical-claims-processingnextjs-performancepayments-pipeline-fixFor every task, the harness built the original Compose environment, started its sandbox, checked that each service was running or had exited successfully, verified every configured health check, and executed
sh -c trueinmain. The source checkout remained clean. All task sandboxes were deleted; final running, starting, and paused sandbox counts were zero, and the isolated server and ublk daemon were stopped.These results do not represent agent success rates or task verifier scores.
Project checks
cargo fmt --all -- --checkcargo clippy --locked --workspace --all-targets --all-features -- -D warningsmake -C services fmt-check vetandgo test ./...fromservices/python3 -u compose-image/test_e2e.py)python3 -u scripts/buildkit/test.py)Compose E2E covers planning without allocations, build args/target/context/
.dockerignore, literal dollars, local image dependency scheduling, successful and failed build cleanup, CLI startup, service DNS/ports/health, original image defaults, pause/resume, fork isolation, snapshot restore, and rejection/failure cleanup. BuildKit E2E covers concurrency, instruction/cache mounts, deadlines, external Dockerfiles/secrets, cancellation/isolation, numeric users, publication after client exit, startup overrides, and terminal progress.Validation fixes include an over-capacity recovery-heartbeat fixture, the guest image builder's missing Protobuf development package, and a redundant
Resultwrapper. Full unrelated hardware/storage suites, optional registry-push E2E, and benchmark solving/scoring were not run in this validation round; the aggregatemake test-unittarget was not used.Image placement validation
go test -race ./gateway/internal ./scheduler/internal.Risks and reviewer notes
Node-local images require eligible capacity holding all required digests; cache eviction can require rebuilding, and creation fails when no such capacity is available. Registry mode provides distribution across nodes. Partial failures may leave imported or pushed images for normal cache/registry retention to reclaim.
Review the server planning endpoint, image-only publication/cleanup, build-result routing, cache inventory replacement, scheduler eligibility checks, and writable service-drive allocation. The plain snapshotter retains active metadata in memory, so independent Docker/containerd/snapshotter restarts are unsupported. Recreating a container reuses its writable rootfs; creating a new sandbox resets it.
Checklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.