Decision: Local Docker build and ACR push capability
Status: implemented
Problem
The custom-template build flow previously supported only platform-side build (uploading the Dockerfile to the backend API), which had the following limits:
- Hard to debug: the build runs remotely, error messages are opaque, and it
cannot be debugged with a local
docker build. - No ACR push capability: platform-side build requires the image to already
exist in ACR (the v2 API
from_imageparameter), but the SDK provided no full chain from local build to ACR push. - CLI lacks a local-build command: users could not perform "build → push →
register template" in one shot through the
abxCLI.
Decision
Add the api/docker_builder.py module, which provides a DockerBuilder class
that encapsulates the full local build → ACR push → template registration flow.
Core flow
- Local Docker build: invoke a
docker buildsubprocess, supporting--platform,--build-arg,--no-cache, and other arguments. - ACR login: use the Alibaba Cloud AK/SK to generate a temporary credential
and run
docker loginagainst the ACR instance. - Image push:
docker tag+docker pushpush the local image to ACR. - Template registration: call the v3 API in
protocol/template.pyto create template metadata, then call the v2 API to trigger the build (withfrom_imagepointing at the ACR image).
New error classes
Three new error classes (E7020–E7022) are added in models/errors.py:
- DockerBuildError(E7020) — local Docker build failed
- ACRPushError(E7021) — ACR push failed
- ACRLoginError(E7022) — ACR login failed
CLI command
Add the abx template build-local subcommand:
abx template build-local ./examples/templates/python-hello \
--acr-namespace my-ns --acr-repo python-hello
abx template build-local ./my-template \
--acr-namespace prod --acree-instance-id cri-xxx
v3/v2 API methods
Two new methods are added in protocol/template.py (aligned with E2B SDK 2.31.0):
- create_v3(name, ...) → POST /v3/templates — create template metadata,
returns templateID + buildID.
- trigger_build_v2(template_id, build_id, from_image, ...) →
POST /v2/templates/{tpl}/builds/{build} — trigger the build from an ACR image.
API Design
# api/docker_builder.py
@dataclass
class ACRConfig:
registry: str # e.g. "registry.cn-hangzhou.aliyuncs.com"
namespace: str
repo: str
username: str # AK ID
password: str # AK Secret
acree_instance_id: str | None = None # ACR EE instance ID
class DockerBuilder:
async def build_and_push(
self,
template_dir: str | Path,
acr_registry: str,
acr_namespace: str,
acr_repo: str,
acr_username: str,
acr_password: str,
*,
acree_instance_id: str | None = None,
platform: str = "linux/amd64",
tag: str | None = None,
no_cache: bool = False,
) -> dict[str, Any]: ...
# protocol/template.py — new methods
class TemplateProtocol:
async def create_v3(self, name, *, dockerfile=None, ...) -> dict[str, Any]: ...
async def trigger_build_v2(
self, template_id, build_id, from_image, *, acr_headers=None, ...
) -> dict[str, Any]: ...
# models/errors.py — new error codes
class DockerBuildError(SandboxError):
code = "E7020"
class ACRPushError(SandboxError):
code = "E7021"
class ACRLoginError(SandboxError):
code = "E7022"
Alternatives considered
- Support platform-side build only (upload the Dockerfile) — hard to debug, slow builds, cannot leverage the local Docker cache. Rejected as the sole option.
- Use the Docker SDK for Python (docker-py) — introduces an extra dependency;
invoking the
dockerCLI viasubprocessis lighter and more transparent to the user. Rejected. - Use the Registry HTTP API v2 for ACR push (bypassing the docker CLI) — requires implementing the full manifest/blob upload protocol; high complexity. Rejected.
- Hardcode AK/SK in the script — security risk; must use environment
variables or a
.envfile. Rejected.
Dependencies
models/errors.py(DockerBuildError/ACRPushError/ACRLoginErrorerror classes)protocol/template.py(create_v3/trigger_build_v2platform-API methods)transport/http.py(HttpClient.platform_requestHTTP request)utils/logging.py(structured logging)- External:
dockerCLI installed locally
Test Strategy
- Unit:
DockerBuilderargument validation,ACRConfigdataclass construction. - Mock: mock
subprocess.runand verify thatdocker build/docker login/docker pushcommands are assembled correctly. - Error scenarios: Docker not installed →
DockerBuildError; wrong ACR credentials →ACRLoginError; push failure →ACRPushError. - CLI:
abx template build-local --helpargument completeness. - E2E: cover the real build → push → register chain in Scenario B of
scripts/e2e/cloud_e2e_test.py.
Acceptance criteria
DockerBuilder.build_and_push()completes the full "build → login → push → register" chain.- The three new error classes (E7020/E7021/E7022) are raised correctly in their respective failure scenarios.
- The
abx template build-localCLI command runs the complete flow. - The v3/v2 API methods in
protocol/template.pyalign with E2B SDK 2.31.0.
Files changed
api/docker_builder.py— new, 851 linesmodels/errors.py— addedDockerBuildError(E7020),ACRPushError(E7021),ACRLoginError(E7022)protocol/template.py— addedcreate_v3(),trigger_build_v2()methodscli/commands/template.py— addedbuild-localsubcommand