iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Docker Build / Push

Build + push Docker images in CI with one or two action steps. Buildx + GitHub Actions cache turns slow Docker builds into 30-second incremental ones.

Multi-arch + cache + scan + sign

EXAMPLE
# .github/workflows/release.yml
name: Release
on:
    push: { tags: ['v*.*.*'] }

permissions:
    contents:  read
    packages:  write
    id-token:  write          # for OIDC + keyless signing

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v4

            # 1) Set up buildx (multi-arch + cache + advanced features)
            - uses: docker/setup-qemu-action@v3      # for non-amd64 archs
            - uses: docker/setup-buildx-action@v3

            # 2) Log into GHCR (or DockerHub / ECR / Quay)
            - uses: docker/login-action@v3
              with:
                  registry: ghcr.io
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}

            # 3) Compute tags / labels — auto-extracts semver + SHA
            - id: meta
              uses: docker/metadata-action@v5
              with:
                  images: ghcr.io/${{ github.repository }}
                  tags: |
                      type=ref,event=tag             # v1.4.0
                      type=sha,format=long           # sha-abc123…
                      type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}

            # 4) Build + push, multi-arch, cached
            - id: build
              uses: docker/build-push-action@v6
              with:
                  context:    .
                  push:       true
                  platforms:  linux/amd64,linux/arm64
                  tags:       ${{ steps.meta.outputs.tags }}
                  labels:     ${{ steps.meta.outputs.labels }}
                  cache-from: type=gha
                  cache-to:   type=gha,mode=max
                  provenance: true
                  sbom:       true

            # 5) Scan the image — fail on critical CVEs
            - uses: aquasecurity/trivy-action@master
              with:
                  image-ref: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
                  severity:  CRITICAL,HIGH
                  exit-code: '1'
                  ignore-unfixed: true

            # 6) Sign keyless via Sigstore
            - uses: sigstore/cosign-installer@v3
            - run: cosign sign --yes \
                ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

Why it matters

cache-from: type=gha + cache-to: type=gha,mode=max is the modern Docker-in-CI unlock. Untouched layers reuse instantly — 30-second builds replace 5-minute ones.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
  with: { username: ${{ secrets.DH_USER }}, password: ${{ secrets.DH_TOKEN }} }
- uses: docker/build-push-action@v6
  with: { push: true, tags: 'me/app:latest,me/app:${{ github.sha }}' }
Try it Yourself »

Exercise

Build + push a Docker image with this action.

uses: docker/ @v6

Discussion

Loading…