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
Hyphenated.
Discussion
Loading…