# Container Builds

If you're looking to use Depot for your container image builds in GitHub Actions, read on.

## Configuration

You can trigger Depot container builds in GitHub Actions using a dedicated build action, a bake action, or the Depot CLI directly. Before configuring your workflow, [set up authentication](/content/docs/container-builds/integrations/github-actions#authentication/index.html).

### 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. See the [action inputs](https://github.com/depot/build-push-action#inputs) for options, including Depot's `project`, `save`, and `save-tags` inputs.

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

The `permissions` block grants the workflow access to the repository contents and allows it to authenticate with Depot via OIDC, so you don't need any secret tokens.

### 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.

```
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    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.

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

## Authentication

[OIDC](/content/docs/cli/authentication#oidc-trust-relationships/index.html) is the recommended authentication method for GitHub Actions. To set it up, add an OIDC trust relationship between your workflow and Depot:

1. Go to your Depot project **Settings**.
2. Click **Add trust relationship**.
3. Select **GitHub** as the provider.
4. Enter the GitHub user or organization name.
5. Enter the repository name (not the full URL, it must match exactly the repository name in GitHub).
6. Click **Add trust relationship**.
7. Add `id-token: write` and `contents: read` to the `permissions` block in your workflow so GitHub can issue the OIDC token.

After its first successful use, a GitHub trust relationship is tied to that repository. It keeps working if you rename or transfer the repository, and a different repository that later takes the old name can't use it.

If you can't use OIDC, you can pass a [project token](/content/docs/cli/authentication#project-tokens/index.html) or [user access token](/content/docs/cli/authentication#user-access-tokens/index.html) via the `token` input or `DEPOT_TOKEN` environment variable instead.

## Registry examples

### Depot Registry

Use the `save` input to store the built image in the [Depot Registry](/content/docs/registry/overview/index.html) 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`.

```
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    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:

```
# 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`.

```
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: 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@v1.6.1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: <aws-region>

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

- 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
    ```

### 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`.

```
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: 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`.

```
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: 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`.

```
name: Build image

on:
  push:
    branches:
      - main

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

- name: Login to DockerHub
        uses: docker/login-action@v2
        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.

```
name: Build image

on:
  push:
    branches:
      - main

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

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

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

- 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.

```
name: Build image

on:
  push:
    branches:
      - main

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

- name: Login to DockerHub
        uses: docker/login-action@v2
        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.

```
name: Build image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    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`.

```
name: Build image with SBOM

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    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@v3.1.0
        with:
          path: ./sbom-output
          name: sbom
    ```
