feat(orchestrator): add export-build command (#3272)#3291
Conversation
…s as Docker image Implements issue e2b-dev#3272. Adds a new CLI tool packages/orchestrator/cmd/export-build that reads an E2B template rootfs from object storage via the NBD block-device pipeline and writes it as a Docker-loadable OCI tar archive or pushes it directly to a container registry. Key changes: - cmd/export-build/main.go: new command with -build/-template/-storage/ -output/-push/-tag flags. Storage and API endpoint are env-configurable so the minimal invocation is just two flags: sudo -E export-build -template <alias> -output /tmp/rootfs.tar - cmd/internal/cmdutil/template.go: extract resolveAPIURL() and add E2B_API_URL env var (highest priority) so self-hosted deployments with a non-standard API host (e.g. http://localhost:3000) work without a domain suffix. - cmd/internal/cmdutil/template_test.go: 12 unit tests covering URL resolution priority and all ResolveTemplateID code paths via httptest. - cmd/export-build/main_test.go: 5 unit tests covering resolveSpec priority chain (flag URL > env var > legacy env).
There was a problem hiding this comment.
Code Review
This pull request introduces the export-build CLI tool to export template rootfs images from E2B object storage as Docker-loadable OCI tar archives or push them to a container registry, alongside supporting updates to API URL resolution. Feedback highlights critical issues with deferring cleanup functions before checking for errors, which could lead to nil pointer dereferences, and recommends using a non-cancellable context for cleanups to ensure they run on interruption. Additionally, it is suggested to lowercase default image tags to avoid Docker repository validation errors and to add a timeout to the template resolution HTTP request to prevent indefinite hangs.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- cleanup: check error before defer, run cleanup with nbdCtx on early return so cleanups are not skipped on failure. Note: all three helpers (TemplateRootfs, GetNBDDevice, MountNBDDevice) always return a non-nil Cleaner, and Cleaner.Run internally calls context.WithoutCancel so the cancel signal does not affect cleanup; the pattern change is for clarity and defensive correctness. - tag: normalise default image tag to lowercase (strings.ToLower) to satisfy Docker repository naming rules when the template alias contains uppercase letters. - template API: add 15s timeout to the template-resolution HTTP request to prevent indefinite hangs when the API is slow or unreachable.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e8232d641
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31d9749292
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary
Implements #3272 — export template/sandbox rootfs as a Docker image.
cmd/export-build/main.go— new CLI tool that mounts a template rootfs via the NBD block-device pipeline and writes it as a Docker-loadable OCI tar archive or pushes it to a container registrycmd/internal/cmdutil/template.go— addsE2B_API_URLenv var for self-hosted deployments where the API lives at a non-standard host (e.g.http://localhost:3000); extractedresolveAPIURL()for testabilitycmd/export-build/main_test.go+cmd/internal/cmdutil/template_test.go— 17 unit tests covering storage resolution priority chain and allResolveTemplateIDcode paths viahttptestUsage
Set env vars once (e.g. in
~/.bashrc):Then export by template alias:
sudo -E export-build -template my-alias -output /tmp/rootfs.tar docker load -i /tmp/rootfs.tar # or push directly to a registry sudo -E export-build -template my-alias -push registry.example.com/img:v1Storage URL priority:
-storageflag →TEMPLATE_STORAGE_URLenv → legacySTORAGE_PROVIDER+TEMPLATE_BUCKET_NAMEenv.API URL priority:
E2B_API_URL→E2B_DOMAIN→https://api.e2b.dev.Prerequisites
modprobe nbd max_part=8 # already loaded on orchestrator nodesTest plan
go test ./cmd/export-build/ ./cmd/internal/cmdutil/passes (17 tests)sudo -E ./export-build -template <alias> -output /tmp/out.tarproduces a loadable tardocker load -i /tmp/out.tar && docker run --rm <image> ls /shows rootfs contents