# Remote builders

Build Docker images on organization-managed remote builders. Reuse persistent layer cache, configure access, and push images directly to the registry.

Remote builders run Docker on Composal and push image layers directly to `registry.composal.ai`. Your workstation sends the build context and receives progress; it does not need to upload the finished image layers through a slow internet connection. Keep build contexts small with `.dockerignore`: source files still need to reach the remote builder.

Each organization manages its own named builders, capacity policy, regions, and persistent caches. Rebuilds reuse unchanged layers and retained BuildKit cache when the Dockerfile and inputs permit it. A cold cache or changed inputs still require work.

## Availability

The Linux `com` 1.17.42 release includes these commands. Production accepts read-only builder list and settings requests, but remote builds are not yet available: the platform gateway has not been deployed or configured. The macOS CLI release is also pending. The examples below describe the tested workflow and will work after the gateway is enabled.

In an isolated test organization, native builds enforced organization capacity, pushed directly to the v2 registry, and reused cached layers after a VM replacement. A 650-second build also renewed its session at the normal ten-minute lifetime. These tests establish the implementation behavior, not production availability.

## Build and push remotely

Sign in with `com login`. Setup creates a missing named builder for an organization administrator; members connect to an existing builder. Use an existing image repository in the same organization, and install Docker locally for its client commands.

```sh
com docker-builder setup main --org acme --context com-acme-main
```

On Unix, `setup` returns the context, implicit Buildx builder, and private local endpoint as JSON. A background supervisor keeps the connection available and wakes the builder when Docker first connects. Configure registry authentication and use the context.

The first Docker connection checks gateway health before waking a sleeping VM. If the gateway is unreachable, the build reports an error without starting remote compute; run setup again after the gateway is restored.

```sh
com docker setup --registry registry.composal.ai
docker --context com-acme-main build -t registry.composal.ai/acme/my-image:dev .
docker --context com-acme-main push registry.composal.ai/acme/my-image:dev
```

Replace `acme`, `main`, and `my-image` with your organization, builder, and image repository slugs. The push destination is `registry.composal.ai/<org-slug>/<image-repository-slug>:<tag>`. These commands leave your current Docker context unchanged. The built image stays on the remote builder; a local image requires an explicit export or pull.

Use [Composal registry](/docs/registry) for repository management and [hosting](/docs/hosting) for deployments that consume your published images. Use `registry.composal.ai` explicitly for setup, login, and image pushes.

## Manage organization builders

`--org` accepts an organization slug or public ID and overrides the checkout organization and configured default. Builder commands accept a builder slug; omitted builder names default to `main`.

```sh
com docker-builder list --org acme
com docker-builder create main --org acme
com docker-builder status main --org acme
com docker-builder wake main --org acme
com docker-builder sleep main --org acme
com docker-builder recover main --org acme
com docker-builder list --org acme --json
```

Members can list, inspect, wake, and connect to builders. Organization administrators create builders, request sleep, and change organization policy. Creating the same slug again reuses its builder and cache. Organizations can create multiple builders, each with its own cache.

Wake provisions asynchronously: status changes from `sleeping` to `starting` and then `ready`. Status includes the startup attempt and current stage. `ready_at` is cleared when a new wake begins. If startup fails, status becomes `failed` with a `startup_failure` reason and the specific stage that failed. Cache maintenance runs at 80% disk or inode usage; retained images may keep usage above that target. Startup is refused at 95% usage to protect the remaining space. Run `com docker-builder wake main --org acme` to retry using the retained cache. A live allocation is reused; replacement requires confirmed termination. Abandoned starts fail after ten minutes. Sleep refuses active operations, checkpoints the cache, and terminates compute while retaining the builder and cache. Status can show `stopping` during that process.

An organization administrator can use `recover` when a lost response leaves an operation occupying the builder. Recovery stops the VM's Docker daemon, checkpoints the cache, marks unfinished operations failed, and sleeps the VM. It interrupts any build still running. New work is refused while recovery is in progress, and the slot stays occupied if the provider cannot confirm the checkpoint. The next build wakes a replacement VM with the same cache identity.

## Configure organization policy

Read settings without flags; updates change only the fields you supply. Policy is shared across the organization's builders.

```sh
com docker-builder settings --org acme
com docker-builder settings --org acme --max-concurrency 2 --idle-timeout-seconds 600
com docker-builder settings --org acme --runtime-timeout-seconds 3600 --region us-east
```

| Setting | Default | Accepted values |
| --- | --- | --- |
| Concurrent operations | 1 | 1 to 32 |
| Idle timeout | 600 seconds | 60 to 86400 seconds |
| Maximum VM lifetime | 3600 seconds | 300 to 86400 seconds |
| Region | `us-east` | `us-east`, `us-west`, `eu-west`, `ap-southeast` |

Idle timeout must be shorter than maximum VM lifetime. Builds and pushes count toward organization capacity. Multiple operations can share a builder’s daemon and cache, up to the organization-wide limit. A competing operation is refused when capacity is occupied. Builder regions are separate from the deployment regions listed in the hosting guide.

## Cache and VM lifecycle

Each builder retains its Docker layers and BuildKit cache across sleep and replacement. Later builds can reuse that cache when their Dockerfile and inputs match.

In one isolated test, a Dockerfile created a 20 MiB random layer on the remote builder from a 1 MiB source payload. Two builds and two direct registry pushes sent about 1.1 MiB from the workstation through the gateway, while the published image contained about 25.7 MiB of compressed layers. The second build reused the cached layer after the VM slept and restarted. Actual transfer and speed depend on your build context, Dockerfile, cache hits, and network.

An idle builder sleeps automatically. Orderly sleep stops Docker, checkpoints storage, and confirms VM termination. The next wake reuses the retained cache. Cache disks have 256 GiB of capacity; smaller retained disks expand during the next wake. Interrupted startup is retried using the same builder generation and cache identity. Cache identity belongs to the builder and is independent of the workstation or individual user. Persistence improves incremental builds; it does not guarantee every rebuild is fast or every step can be cached.

For disposable images that you have pushed to a registry, add the Docker image label `ai.composal.cache-only=true`. Under disk or inode pressure, Composal can reclaim unused builder copies with this label at any age. Keep the label off images you need to retain on the builder.

## Access and connections

Background setup uses a private Unix socket; foreground connect accepts loopback TCP or a socket in a private directory. Both use your existing Composal login. Short-lived builder sessions are scoped to your organization, actor, builder, and VM generation. The proxy renews sessions while connected, installing the replacement before revoking the previous session. Background connections using your saved login reread it for API requests and refuse credentials if the login now belongs to another API. Explicit token overrides remain in memory; disconnect and rerun setup to replace an override.

The platform gateway checks current organization access and capacity for native build operations. This connection supports native Docker builds with embedded BuildKit, pushes, and permitted inspection APIs. It is not a general-purpose remote container execution endpoint; Docker-container Buildx drivers that require container creation or execution are not supported through this gateway.

The foreground proxy must remain running while Docker uses its context; the default Unix setup supervises it in the background. Stopping it closes local connections and stops accepting new ones. It does not prove an admitted remote operation has stopped or immediately release its capacity slot.

## Failures and recovery

If Composal confirms a VM has terminated unexpectedly, reconciliation fails stranded operations and retains the builder's cache identity for replacement. Previously committed cache survives; writes interrupted before persistence may be lost. An uncertain VM status keeps capacity occupied instead of assuming a build has finished.

A final build result from the remote daemon releases capacity, including a failed Dockerfile step. Socket closure, expired sessions, cancellation requests, and lost daemon responses do not by themselves establish remote completion. An organization administrator can use `com docker-builder recover` to checkpoint and stop a still-running VM before releasing abandoned work. Inspect builder status if capacity remains occupied; reconnecting does not erase an existing operation.

## Docker context setup

`com docker-builder setup` creates a Docker context and its implicit Buildx builder with the embedded `docker` driver. A missing slug is created through the organization API, which requires administrator permission; public IDs must already exist. It checks that the platform gateway is configured before changing local context metadata. An existing context is updated only if it belongs to the same organization builder and API; use `--context` to choose another name when a name is already in use. Docker and its Buildx plugin must be installed locally. A successful `setup` confirms that the local proxy is listening. Run `docker --context com-acme-main version` to check the remote daemon.

Unix setup uses a private per-user socket with a stable path. Repeating setup reuses a healthy supervisor. A failed worker is restarted on the same endpoint; workers also stop if their supervisor exits. Run setup again after stopping the supervisor or restarting your machine. Interruptions do not replay an in-progress remote build.

```sh
com docker-builder disconnect main --org acme
com docker-builder setup main --org acme --context com-acme-main --foreground
```

`disconnect` stops your local background connection; it does not sleep the remote builder or prove a remote build has finished. Foreground setup must remain running in its terminal. Background setup is currently Unix-only; use `--foreground` on other platforms. For manual context management, use `com docker-builder connect main --org acme --listen 127.0.0.1:23750` and create a Docker context pointing to that endpoint. `wake` alone does not configure Docker.

See the [CLI reference](/docs/cli) for other commands and the [API reference](/docs/api) for organization builder and session contracts.


## Retained cache pricing

Retained Docker cache storage is $0.50 per decimal GB per calendar month,
prorated from measured retained bytes. A sleeping builder retains its cache,
so storage continues to accrue while compute is stopped. Sparse unused backing
file capacity is excluded. Existing negotiated rates take precedence.
