# Container builds in Depot CI (https://depot.dev/docs/container-builds/integrations/depot-ci)

You can use Depot for your container image builds inside Depot CI workflows.

If you haven't migrated your GitHub Actions workflows to Depot CI yet, see the [Depot CI quickstart](/docs/ci/quickstart). Depot CI workflows are compatible with GitHub Actions YAML. For details, see the [Depot CI compatibility reference](/docs/ci/compatibility).

## Configuration

You can trigger Depot container builds in Depot CI using a dedicated build action, a bake action, or the Depot CLI directly.

### Depot build-push action

The [`depot/build-push-action`](https://github.com/depot/build-push-action) implements the same inputs and outputs as `docker/build-push-action` but uses the Depot CLI to run the build. Use [`depot/setup-action`](https://github.com/depot/setup-action) to install the Depot CLI first.

```yaml
jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1
      - uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
```

### Depot bake action

The [`depot/bake-action`](https://github.com/depot/bake-action) builds all images defined in an HCL, JSON, or Docker Compose file. Use it when you need to build multiple images in a single build request.

```yaml
jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1
      - uses: depot/bake-action@v1
        with:
          project: <your-depot-project-id>
          files: docker-bake.hcl
```

### Depot CLI

The [`depot/setup-action`](https://github.com/depot/setup-action) installs the `depot` CLI so you can run builds directly from your existing workflows.

```yaml
jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1
      - run: depot build --project <your-project-id> --push --tag repo/image:tag .
```

## Authentication

Depot CI automatically injects `DEPOT_TOKEN` into every job as a short-lived CI job token with full access to your organization's projects and registry. You don't need to configure OIDC trust relationships or store any secrets, the build authenticates without additional setup.

If you set `DEPOT_TOKEN` as a workflow secret yourself, your value overrides the auto-injected token. This commonly happens after migrating from GitHub Actions, where `DEPOT_TOKEN` was a project token. A project token is scoped to a single project's repositories in the Depot Registry, so pushes to repositories that don't begin with that project ID will fail. To restore the auto-injected behavior, remove the `DEPOT_TOKEN` secret from the dashboard or with `depot ci secrets remove DEPOT_TOKEN`.

## Pulling private base images

Dockerfiles that start with `FROM` referencing a private registry need credentials when Depot builds the image. You have two options.

### Pull through Depot Registry (recommended)

Configure your private registry as an upstream once from [Registry settings](/orgs/_/registry/settings), then create a Depot repository that mirrors the upstream and reference the Depot Registry URL in your Dockerfile:

```dockerfile
FROM <orgId>.registry.depot.dev/<repository>:<tag>
```

Depot fetches the image from your upstream registry, caches layers on its global CDN, and serves subsequent pulls from the cache. The auto-injected `DEPOT_TOKEN` handles pull authentication, so no login step is needed in the workflow. See [Pull-through cache](/docs/registry/pull-through-cache) for setup details and supported providers.

### Authenticate to the upstream registry

If pull-through isn't an option, log in to the upstream registry before the build step using `docker/login-action`. The Depot remote builder picks up the credentials and uses them for `FROM` pulls.

```yaml
jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Login to private registry
        uses: docker/login-action@v3
        with:
          registry: private-registry.example.com
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}

      - uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
```

## Registry examples

### Depot Registry

Use the `save` input to store the built image in the [Depot Registry](/docs/registry/overview) without any additional login steps. You can tag the image with `save-tag` or `save-tags` to retrieve it later with `depot pull` or `docker pull`.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Build and save to Depot Registry
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          save: true
          save-tags: |
            latest
            ${{ github.sha }}
```

The saved image can then be pulled from the Depot Registry:

```shell
# Using the Depot CLI (uses existing CLI credentials)
depot pull --project <your-depot-project-id> latest

# Using Docker (requires docker login first)
docker login registry.depot.dev -u x-token -p $(depot pull-token --project <your-depot-project-id>)
docker pull registry.depot.dev/<your-depot-project-id>:latest
```

### Amazon ECR

Use the [`aws-actions/configure-aws-credentials`](https://github.com/aws-actions/configure-aws-credentials) and [`aws-actions/amazon-ecr-login`](https://github.com/aws-actions/amazon-ecr-login) actions to authenticate to your ECR registry, then build and push with `depot/build-push-action`. AWS authentication uses the OIDC token Depot CI issues when you set `id-token: write`.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::<account-id>:role/<role-name>
          aws-region: <aws-region>

      - name: Login to Amazon ECR
        id: ecr-login
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          push: true
          tags: ${{ steps.ecr-login.outputs.registry }}/<your-app>:latest
```

For the OIDC trust relationship setup on the AWS side, see [OIDC with Depot CI](/docs/ci/oidc).

### GCP Artifact Registry

Use the [`google-github-actions/auth`](https://github.com/google-github-actions/auth) and [`google-github-actions/setup-gcloud`](https://github.com/google-github-actions/setup-gcloud) actions to authenticate to your Artifact Registry, then build and push with `depot/build-push-action`.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - uses: google-github-actions/auth@v3
        with:
          service_account: '...'
          workload_identity_provider: '...'

      - uses: google-github-actions/setup-gcloud@v3
        with:
          project_id: <gcp-project-id>

      - name: Configure docker for GCP
        run: gcloud auth configure-docker <gcp-region>-docker.pkg.dev --quiet

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          push: true
          tags: <gcp-region>-docker.pkg.dev/<gcp-project-id>/<your-app>:latest
          provenance: false
```

### Azure Container Registry

Use the [`azure/login`](https://github.com/azure/login) action to authenticate with Azure, then `az acr login` to obtain a registry token before building and pushing with `depot/build-push-action`.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: Login to Azure Container Registry
        run: az acr login --name <registry-name>

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          push: true
          tags: <registry-name>.azurecr.io/<image-name>:<tag>
```

### Docker Hub

Use the [`docker/login-action`](https://github.com/docker/login-action) to authenticate to Docker Hub, then build and push with `depot/build-push-action`.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          push: true
          tags: user/app:latest
```

### Multiple registries

Log in to each registry individually and pass multiple tags to push the image to all of them.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::<account-id>:role/<role-name>
          aws-region: <aws-region>

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to Amazon ECR
        id: ecr-login
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          push: true
          tags: |
            <docker-hub-organization>/<your-app>:latest
            ${{ steps.ecr-login.outputs.registry }}/<your-app>:latest
```

## Other examples

### Multi-platform images

Use the `platforms` input to build for Intel and Arm architectures natively without emulation.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: user/app:latest
```

### Export an image to Docker

By default, Depot doesn't return the built image to the client. Pass `load: true` to make the image available in your workflow for subsequent steps like integration tests.

```yaml
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Build and load
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          load: true
          tags: test-container

      - name: Run integration test with built container
        run: ...
```

### Software Bill of Materials

Use the `sbom` and `sbom-dir` inputs to generate an SBOM for the image and output it to a directory. You can then upload it as a build artifact with `actions/upload-artifact`.

```yaml
name: Build image with SBOM

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: depot-ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depot/setup-action@v1

      - name: Build with SBOM
        uses: depot/build-push-action@v1
        with:
          project: <your-depot-project-id>
          context: .
          sbom: true
          sbom-dir: ./sbom-output

      - name: Upload SBOM
        uses: actions/upload-artifact@v4
        with:
          path: ./sbom-output
          name: sbom
```

## For AI Agents

The full site index is at [llms.txt](https://depot.dev/llms.txt). Append `.md` to any documentation, blog, changelog, or customer URL to fetch its markdown source directly.