mcpField
D
depot-container-builds

depot-container-builds

github.com/depotCloud & DevOps2289 installsUpdated 6d ago
Repository

About depot-container-builds

Depot Container Builds is a remote Docker image build tool for container developers and CI workflows, with `depot build` and `depot bake` commands. It manages caching automatically and supports parallel multi-image and native multi-platform builds.

Key features

  1. 01Run Docker image builds remotely
  2. 02Manage NVMe build cache automatically
  3. 03Build multiple images in parallel
  4. 04Build natively for amd64 and arm64
  5. 05Output to local Docker or registries
  6. 06Configure build autoscaling

Use cases

  1. 01Replace docker build with remote builds
  2. 02Build Docker Compose services in parallel
  3. 03Build and push multi-platform images
  4. 04Generate SBOM attestations for images

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/depot/skills --skill depot-container-builds

After installing, type/depot-container-buildsin Claude Code to confirm it loaded.

Bundled filesagents/openai.yaml

Details

From the project README

Depot Container Builds

Depot runs Docker image builds on remote high-performance builders (16 CPU, 32 GB RAM, NVMe SSD cache). depot build is a drop-in replacement for docker build / docker buildx build. depot bake replaces docker buildx bake.

Project Selection for Multi-Org Users

Container build commands target a specific project, not an organization. If expected projects aren't visible or a build unexpectedly prompts to select a project, the current default org may be wrong:

depot org show              # Current org ID
depot org list              # Orgs the user belongs to
depot org switch <org-id>   # Optional: set default org

Key Concepts

  • Builds run remotely on ephemeral EC2 instances — images stay in remote cache by default
  • Use --load to download to local Docker, --push to push to a registry, --save to store in Depot's ephemeral registry
  • Cache is fully automatic on persistent NVMe SSDs — no manual cache config needed
  • Multi-platform builds use native CPU builders (no QEMU emulation) for amd64 and arm64 simultaneously
  • All team members on a project share the same layer cache

depot build — Essential Patterns

# Build remotely (image stays in remote cache)
depot build -t repo/image:tag .

# Build + download to local Docker daemon
depot build -t repo/image:tag . --load

# Build + push directly to registry (fast — doesn't route through local network)
depot build -t repo/image:tag . --push

# Multi-platform build (native CPUs, no emulation)
depot build --platform linux/amd64,linux/arm64 -t repo/image:tag . --push

# Save to Depot ephemeral registry (7-day default, configurable per repository)
depot build --save .
depot build --save --save-tag my-tag .

# Suppress provenance metadata (fixes "unknown/unknown" platform in registries)
depot build -t repo/image:tag --push --provenance=false .

# Lint Dockerfile before building
depot build -t repo/image:tag . --lint

# Build with secrets
depot build --secret id=mysecret,src=./secret.txt -t repo/image:tag .

# Build with SSH forwarding
depot build --ssh default -t repo/image:tag .

# Specify a Depot project explicitly
depot build --project <project-id> -t repo/image:tag .
Key Flags
FlagDescription
--loadDownload image to local Docker daemon
--pushPush to registry
--saveSave to Depot ephemeral registry
--save-tagCustom tag for Depot Registry
--platformTarget platforms: linux/amd64, linux/arm64 (native, no emulation), plus linux/arm/v6, linux/arm/v7, linux/386
--build-platformForce build to run on specific arch (dynamic default)
--projectDepot project ID
--tokenDepot API token
--lintLint Dockerfile before build
--provenanceControl provenance attestation (set false to fix unknown/unknown)
--sbomGenerate an SBOM attestation (shorthand for --attest type=sbom)
--sbom-dirDirectory to store SBOM attestations
--attestAttestation parameters (for example type=sbom,generator=image)
--no-cacheDisable cache for this build
-f / --filePath to Dockerfile
-t / --tagImage name and tag
--targetBuild specific stage
--build-argSet build-time variables
--secretExpose secrets (id=name[,src=path])
--sshExpose SSH agent
--output / -oCustom output (type=local,dest=path)

Cancel Container Builds

Use depot build cancel only when cancellation is requested. Supply an organization API token through --token or DEPOT_TOKEN; project tokens, reader tokens, legacy login tokens, and CI OIDC credentials cannot cancel builds.

depot build cancel <build-id> <another-build-id>
depot build cancel --all-running --project <project-id> --dry-run
depot build cancel --all-running --project <project-id> --yes --output json

Choose explicit build IDs or --all-running --project, not both. Bulk selection requires an explicit project; depot.json and DEPOT_PROJECT_ID do not supply it. Preview bulk cancellation with --dry-run; use --yes only for authorized non-interactive cancellation. Selection excludes builds started afterward.

Cancellation is asynchronous: success means the request was accepted, not that execution stopped. Finished builds are successful no-ops. JSON reports each build's outcome or error; any failed request makes the command fail.

depot bake — Multi-Image Builds

Drop-in replacement for docker buildx bake. Builds multiple images in parallel.

depot bake                                    # Default file lookup
depot bake -f docker-bake.hcl                 # Specific HCL file
depot bake -f docker-compose.yml --load       # Build compose services + load locally
depot bake --save --save-tag v1               # Save as v1-<target-name> in Depot Registry
depot bake --print                            # Print resolved config without building

Default file lookup order: compose.yaml → compose.yml → docker-compose.yml → docker-compose.yaml → docker-bake.json → docker-bake.hcl → docker-bake.override.json → docker-bake.override.hcl

Without target arguments, depot bake builds the default group. Saved tags use <build-id>-<target-name>; --save-tag v1 adds v1-<target-name>. Use --save --push to save in Depot Registry and push the configured target tags. Set project_id in an HCL target to select its Depot project.

HCL Bake File Example
variable "TAG" {
  default = "latest"
}

group "default" {
  targets = ["app", "worker"]
}

target "app" {
  dockerfile = "Dockerfile"
  platforms  = ["linux/amd64", "linux/arm64"]
  tags       = ["myrepo/app:${TAG}"]
  args = { NODE_VERSION = "20" }
}

target "worker" {
  dockerfile = "Dockerfile.worker"
  tags       = ["myrepo/worker:${TAG}"]
  contexts   = { app = "target:app" }  # Share base between targets
}

Override variables: TAG=v2.0 depot bake

Docker Compose with Per-Service Project IDs
services:
  api:
    build:
      dockerfile: ./Dockerfile.api
      x-depot:
        project-id: abc123
  web:
    build:
      dockerfile: ./Dockerfile.web
      x-depot:
        project-id: def456

Docker Compose Integration

# Preferred: build all services in parallel, then load
depot bake -f docker-compose.yml --load
docker compose up

# Alternative: zero code change (less efficient, each service = separate build)
depot configure-docker
docker compose build

Migration from Docker

# docker build → depot build (same flags, one-line swap)
depot build -t my-image .

# docker buildx bake → depot bake
depot bake -f docker-bake.hcl

# Zero code change via Docker plugin
depot configure-docker
docker build .  # Routes through Depot (look for [depot] prefix in logs)

When migrating, remove these flags — Depot handles caching automatically:

  • --cache-from type=gha — causes "services aren't available" errors
  • --cache-to type=gha — same issue
  • Any manual BuildKit cache configuration

Common Mistakes

MistakeFix
Using --cache-from type=gha or --cache-to type=ghaRemove them. Depot caches automatically on NVMe SSDs.
Multi-platform image shows unknown/unknown platformAdd --provenance=false
Expecting image locally after depot buildAdd --load to download, or --push to push to registry
.git directory missing in build contextAdd --build-arg BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
Build hangs or "failed to mount" errorsReset cache in project settings or via depot cache reset
"401 Unauthorized" pulling base imagesDocker Hub rate limit — authenticate with docker login or use public.ecr.aws/docker/library/ mirror
--load fails with "client version 1.43 is too old"Docker Engine v29 raised the minimum API version to 1.44 — prefix the build with DOCKER_API_VERSION=1.52 depot build --load .
"Keep alive ping failed" / OOMScale up builder size in project settings or enable autoscaling

Builder Sizes

SizeCPUsRAMPer-MinuteMinutes multiplierPlans
Default1632 GB$0.041xAll
Large3264 GB$0.082xStartup+
Extra Large64128 GB$0.164xStartup+

Billed per-second. Large and Extra Large builders consume your included build minutes faster (via the multiplier) in addition to costing more per minute.

Build Autoscaling

Autoscaling is disabled by default, so Depot routes a project's builds for each architecture to one builder. Enable horizontal autoscaling in the project settings when concurrent builds need separate builders. The settings form preselects 16 builds per instance; Depot starts another builder when concurrent builds reach the configured limit.

Each builder has an independent cache. Heavy autoscaling can reduce cache efficiency, so try a larger builder first when one build needs more CPU or memory. Autoscaling is available on all plans without an additional fee.

One depot bake invocation counts as one build for autoscaling, regardless of its target count. Separate project IDs create separate build requests.

Configure autoscaling from the CLI with an organization API token:

depot projects update <project-id> --max-concurrent-builds 3
depot projects update <project-id> --disable-autoscaling

The positive limit applies per builder instance. The two update flags are mutually exclusive; omitting both preserves the current setting. depot projects create <name> --max-concurrent-builds 3 enables autoscaling for a new project; creation without the flag leaves autoscaling disabled.

Depot Registry

An OCI-compliant registry that works both as a lightweight ephemeral store for build output and as a full primary registry for all your images (including ones not built with Depot). Each org gets its own subdomain {orgId}.registry.depot.dev, backed by a global CDN, and stores images and OCI artifacts (Helm charts, AI models) up to 50 GB. Browse repositories, tags, and attestations in the Registry Explorer in the dashboard.

# Save a Depot build's output to the registry (project-scoped, no tagging step)
depot build --save -t myapp .

# Push any image to Depot Registry as a primary registry
docker push {orgId}.registry.depot.dev/your/app:v1

# Pull a saved project image (by build ID or by tag)
depot pull --project <id> <build-id>
depot pull --project <id> my-image:tag
depot pull --project <id> --platform linux/arm64 <build-id>   # pull a specific platform

# Generate a 1-hour read-only token for the project's registry paths
depot pull-token --project <id>
depot pull-token --project <id> <build-id>                    # scoped to a specific build

# Push saved image to another registry
depot push --project <id> -t registry/image:tag <build-id>

# List saved images as JSON
depot image list --project <id> --output json

# Delete selected image tags only when requested
depot image rm --project <id> app:old app:staging

# Docker auth for Depot Registry (each org has its own subdomain)
docker login {orgId}.registry.depot.dev -u x-token
# Enter a scoped registry access token at the password prompt.
# Registry URL: {orgId}.registry.depot.dev/your/app:tag
# (the legacy registry.depot.dev/<project-id>:<build-id> form still works for existing usage)

Image retention defaults to 7 days but is configurable per repository from the Registry Explorer, either by age (1, 7, 14, or 30 days) or by tag count (5, 10, 25, 50, or 100 tags).

For custom image names, use a registry access token. Organization owners create tokens in Registry Settings → Registry access tokens. Select Pull or Push permission; Push includes pull access. Scope tokens to exact paths (frontend), one level (team/*), any depth (team/**), or all repositories (**). Exclude registry hostnames and image tags from scopes.

Use depot pull for saved project builds and tags, and docker pull for custom or pull-through repositories. CLI pull tokens cover only <project-id> and its descendant paths. Use a registry access token with Pull permission for other names.

Pull-through cache: Depot Registry can proxy an external registry and cache its layers on the CDN, so repeat pulls skip the upstream hop (faster CI pulls, global distribution, simpler auth for registries like Google Artifact Registry). Configure an upstream in Registry Settings; supported providers are Docker Hub, GitHub Container Registry, GitLab Container Registry, Quay.io, AWS ECR, Google Artifact Registry, Azure Container Registry, and custom registries. Pull-through must be set when the repository is created, it can't be added to an existing repository.

Cached mutable tags such as latest are not refreshed from upstream on every pull. Use a new immutable tag or digest to select updated content. Missing or reclaimed content still requires the upstream registry, so caching does not guarantee availability during an upstream outage.

Special Output Formats

# estargz (lazy-pulling for faster container startup)
depot build --output "type=image,name=repo/image:tag,push=true,compression=estargz,oci-mediatypes=true,force-compression=true" .

# zstd compression (faster Fargate/K8s startup)
depot build --output type=image,name=repo/image:tag,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true,push=true .

# SOCI v2 (lazy-loading for faster startup of large images, for example CUDA/PyTorch)
depot build -t repo/image:tag --push --output type=image,soci=true,compression=gzip,force-compression=true,oci-mediatypes=true .

SOCI only indexes gzip layers, so compression=gzip is required and force-compression=true ensures every layer (including base-image layers) is indexed. The index is written alongside unchanged layers in the registry, so there's no separate post-push step; layers under 10 MB are skipped by default (soci-min-layer-size to change). To get the startup benefit, the pulling platform must use the SOCI snapshotter: AWS Fargate does this automatically, and Amazon EKS/EC2 or your own hosts need the soci-snapshotter enabled in containerd.

Comments

Markdown supported