docs/build/ci/github-actions/named-contexts.md

3.7 KiB

title keywords
Named contexts with GitHub Actions ci, github actions, gha, buildkit, buildx, context

You can define additional build contexts, and access them in your Dockerfile with FROM name or --from=name. When Dockerfile defines a stage with the same name it's overwritten.

This can be useful with GitHub Actions to reuse results from other builds or pin an image to a specific tag in your workflow.

Pin image to a tag

Replace alpine:latest with a pinned one:

# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"

{% raw %}

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      -
        name: Build
        uses: docker/build-push-action@v4
        with:
          context: .
          build-contexts: |
            alpine=docker-image://alpine:3.16            
          tags: myimage:latest

{% endraw %}

Use image in subsequent steps

By default, the Docker Setup Buildx{:target="blank" rel="noopener" class=""} action uses docker-container as a build driver, so built Docker images aren't loaded automatically.

With named contexts you can reuse the built image:

# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"

{% raw %}

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
        with:
          driver: docker
      -
        name: Build base image
        uses: docker/build-push-action@v4
        with:
          context: ./base
          file: ./base/Dockerfile
          load: true
          tags: my-base-image:latest
      -
        name: Build
        uses: docker/build-push-action@v4
        with:
          context: .
          build-contexts: |
            alpine=docker-image://my-base-image:latest            
          tags: myimage:latest

{% endraw %}

Using with a container builder

As shown in the previous section we are not using the default docker-container driver for building with named contexts. That's because this driver can't load an image from the Docker store as it's isolated. To solve this problem you can use a local registry to push your base image in your workflow:

# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    services:
      registry:
        image: registry:2
        ports:
          - 5000:5000
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v2
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
        with:
          # network=host driver-opt needed to push to local registry
          driver-opts: network=host
      -
        name: Build base image
        uses: docker/build-push-action@v4
        with:
          context: ./base
          file: ./base/Dockerfile
          tags: localhost:5000/my-base-image:latest
          push: true
      -
        name: Build
        uses: docker/build-push-action@v4
        with:
          context: .
          build-contexts: |
            alpine=docker-image://localhost:5000/my-base-image:latest            
          tags: myimage:latest