Images in CI and Registries
Tagging strategy
Tag images so you always know what is running and can roll back:
- the Git commit SHA:
ghcr.io/you/myapp:3f1c2a9 - a release version:
ghcr.io/you/myapp:1.4.0 - optionally a moving tag such as
mainfor the latest build
Avoid deploying latest in production: it is ambiguous and makes rollbacks hard.
Building and pushing in GitHub Actions
name: image
on:
push:
branches: [main]
permissions:
contents: read
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.sha }}
ghcr.io/${{ github.repository }}:main
cache-from: type=gha
cache-to: type=gha,mode=max
The GitHub Actions cache keeps layer caching between runs, so builds stay fast.
Scan before you ship
Add a vulnerability scan step (Trivy or Docker Scout) that fails the build on critical issues with available fixes.
Multi-architecture images
Many servers (and Apple Silicon Macs) are ARM. docker buildx build --platform linux/amd64,linux/arm64 builds both from one Dockerfile.
Exercise
Set up a workflow that builds your image on every push to main, tags it with the commit SHA, pushes it to GitHub Container Registry with layer caching and scans it.
Check yourself
- Why tag images with the commit SHA?
- Why avoid
latestin production? - What does build caching in CI save?
Your progress is saved in this browser only.
Submit for review (10 points)