arcbox-docker 0.6.3

Docker REST API compatibility layer for ArcBox
docs.rs failed to build arcbox-docker-0.6.3
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

arcbox-docker

Docker REST API compatibility layer for ArcBox.

Overview

This crate provides a Docker-compatible API server that allows existing Docker CLI tools to work with ArcBox seamlessly. It acts as a host-side compatibility and proxy layer: some endpoints are handled by ArcBox handlers while pass-through requests are forwarded to guest dockerd.

Features

  • Container Operations: create, start, stop, kill, rm, ps, inspect, logs, exec, attach, wait, pause, unpause, top, stats
  • Image Operations: pull, push, list, remove, tag, prune
  • Volume Operations: create, list, inspect, remove, prune
  • Network Operations: list, inspect, create, remove (basic)
  • System Operations: info, version, ping, events, df

Usage

The server listens on a Unix socket that can be configured as a Docker context:

# Create and use ArcBox Docker context
docker context create arcbox --docker "host=unix://$HOME/.arcbox/docker.sock"
docker context use arcbox

# Now Docker CLI uses ArcBox
docker ps
docker run alpine echo hello
docker images

Architecture

flowchart LR
    cli[Docker CLI / API client]
    socket[ArcBox Docker Unix socket]
    version[Version prefix stripper<br/>/v1.xx removed for routing]
    trace[Trace middleware<br/>X-Trace-Id + tracing span]
    context[Request-context middleware<br/>resolve UtilityVmRole once]
    router[Axum router]
    handlers[ArcBox handlers<br/>only endpoints with host-side behavior]
    fallback[Smart fallback<br/>ordinary pass-through]
    proxy{Proxy protocol path}
    forward[forward.rs<br/>pooled HTTP/1.1]
    upload[upload.rs<br/>streamed uploads]
    upgrade[upgrade.rs<br/>HTTP upgrade tunnel]
    connector[connector.rs<br/>role → VM vsock]
    dockerd[guest dockerd]

    cli --> socket --> version --> trace --> context --> router
    router -->|create/start/stop/remove/build/exec-create| handlers
    router -->|all other Docker endpoints| fallback
    handlers --> proxy
    fallback --> proxy
    proxy -->|ordinary HTTP| forward
    proxy -->|build context / image load| upload
    proxy -->|attach / exec / BuildKit session| upgrade
    forward --> connector
    upload --> connector
    upgrade --> connector
    connector --> dockerd

The router strips Docker API version prefixes before route matching and stores the original URI for proxy forwarding. A request-context middleware derives the target utility VM role once from the URI and stores it in request extensions. Requests then take one of three paths:

  • Local handlers implement ArcBox-owned behavior such as host path normalization, workload role tracking, and lifecycle orchestration. The route table intentionally contains only these endpoints.
  • Ordinary pass-through uses the Axum fallback for endpoints that do not need ArcBox-specific behavior, then relays non-upgrade HTTP/1.1 requests to guest dockerd through a pooled hyper client.
  • Special proxy forwarding handles streaming uploads and HTTP upgrades with dedicated connection lifecycles instead of the ordinary pool.

Tracing spans are created at the request, routing, role-resolution, proxy, and guest-connection boundaries. When arcbox-daemon runs with Sentry enabled, the Sentry tracing layer receives these fields as context/breadcrumbs for Docker proxy failures without logging request bodies or sensitive headers.

Proxy Design

The proxy is split by protocol behavior rather than Docker endpoint category:

flowchart TB
    fallback[fallback.rs<br/>protocol classifier]
    direct[Explicit handlers<br/>host-side side effects]
    pooled[forward.rs<br/>GuestHttpClient]
    session[session.rs<br/>hyper-util pool]
    upload[upload.rs<br/>bounded body pump]
    upgrade[upgrade.rs<br/>raw upgrade handshake]
    headers[headers.rs<br/>end-to-end header filtering]
    uri[uri.rs<br/>guest path/query]
    connector[connector.rs<br/>VsockConnector]

    fallback -->|non-upgrade HTTP| pooled
    direct -->|ordinary proxied subcalls| pooled
    fallback -->|large upload| upload
    fallback -->|Connection: Upgrade| upgrade
    pooled --> session
    pooled -. normalizes .-> uri
    upload -. filters .-> headers
    upload -. normalizes .-> uri
    upgrade -. raw HTTP head .-> uri
    session --> connector
    upload --> connector
    upgrade --> connector
Module Responsibility
connector.rs Production vsock connection establishment via arcbox-core runtime
forward.rs Ordinary HTTP/1.1 request/response forwarding
upload.rs Large streamed upload requests, including build contexts and image loads
upgrade.rs HTTP upgrade tunnels for attach, exec, and BuildKit-style streams
fallback.rs Catch-all forwarding for routes not explicitly handled by Axum
headers.rs End-to-end header filtering and forwarding rules
session.rs Guest HTTP client/session setup and pooled client adapter
uri.rs Guest path/query normalization

Ordinary HTTP forwarding

Ordinary non-upgrade requests use GuestHttpClient, which wraps hyper-util::client::legacy::Client with HTTP/1.1 connection pooling:

  • up to 8 idle guest connections per internal authority;
  • 30 second idle timeout;
  • response bodies stream back to the Docker CLI without full buffering;
  • hyper-util returns a connection to the pool only after the response body is fully consumed, and discards it if the body is dropped early or errors.

The pool key is the request URI authority, so ArcBox uses internal authorities to separate utility VM roles:

flowchart LR
    native[http://native.arcbox.internal/...] --> nativeRole[UtilityVmRole::Native]
    rosetta[http://rosetta.arcbox.internal/...] --> rosettaRole[UtilityVmRole::Rosetta]
    nativeRole --> nativePool[Native idle connection pool]
    rosettaRole --> rosettaPool[Rosetta idle connection pool]

The internal authority is only for hyper-util pooling and role selection. The guest request still carries Host: localhost and is sent over the selected vsock connection.

Upload and upgrade paths

Streaming uploads and HTTP upgrades intentionally do not use the ordinary pooled client:

  • upload forwarding can return the guest response while the client request body is still draining in the background;
  • upgrade forwarding takes ownership of the raw HTTP/1.1 connection and then tunnels bytes after the 101 Switching Protocols response.

Keeping these paths on dedicated connections avoids corrupting pooled HTTP/1.1 state with partially-drained request bodies or upgraded protocols.

Guest transport

Production proxy connections are opened through VsockConnector, which asks arcbox-core for the selected utility VM's dockerd vsock port. The underlying file descriptor is wrapped by arcbox_transport::vsock::VsockStream, giving the proxy one async stream abstraction for both production vsock and Unix-socket integration tests.

Guest Docker readiness

arcbox-core owns the slow readiness path: starting the utility VM, asking the guest agent to ensure the container runtime, and validating the reported vsock endpoint. arcbox-docker owns Docker HTTP readiness because only the proxy can prove that guest dockerd accepted and answered a real Docker request.

Before a request is forwarded, ProxyState asks GuestDockerReadiness to verify the selected UtilityVmRole. Readiness is tracked per role with an explicit state machine:

stateDiagram-v2
    [*] --> Unverified
    Unverified --> Verifying: prepare runtime + GET /_ping
    Verifying --> Verified: success
    Verifying --> Unverified: prepare or _ping failed
    Verified --> Unverified: transport/proxy failure

Only one caller performs the runtime preparation and _ping while a role is in Verifying; concurrent callers wait for the state change and then reuse the result. Any forwarding, upload, or upgrade transport error invalidates that role's readiness so the next request re-runs the slow readiness path and then verifies guest dockerd with another _ping.

This keeps the ownership boundary clear:

  • arcbox-core: VM lifecycle, guest agent runtime readiness, endpoint shape.
  • arcbox-docker: HTTP verification, readiness caching, transport-failure invalidation.

API Version

  • Host route compatibility: /v1.24 through /v1.43 plus unversioned routes
  • Version payload source: /version and related system metadata are reported by guest dockerd

Testing

Focused proxy checks:

cargo test -p arcbox-docker proxy::
cargo test -p arcbox-docker --test proxy_integration
cargo test -p arcbox-docker api::tests::readiness

The integration tests run against a mock guest dockerd over a Unix socket, so they do not require a VM. They cover ordinary forwarding, pooled session reuse, early body-drop discard behavior, streaming forwarding, and HTTP upgrade handling. The readiness unit tests cover the explicit state transitions, per-role isolation, invalidation, and concurrent verification serialization.

License

MIT OR Apache-2.0