GitHub Actions Tutorial — Deploy Docker Images
Deploy Docker Images
Building and pushing container images is one of the most common deployment tasks. GitHub Actions supports Docker Hub, GitHub Container Registry (GHCR), Amazon ECR, Azure ACR, and any OCI-compatible registry.
GitHub Container Registry (GHCR)
name: Build and Push to GHCR
on:
push:
branches: [main]
permissions:
contents: read
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha
type=ref,event=branch
type=semver,pattern={{version}}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Docker Hub
steps:
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: my-org/my-app:${{ github.sha }}
Amazon ECR
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: aws-actions/amazon-ecr-login@v2
id: ecr
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.ecr.outputs.registry }}/my-app:${{ github.sha }}
Multi-Platform Builds
Build images for multiple architectures:
steps:
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/${{ github.repository }}:latest
Build Cache
Speed up builds with layer caching:
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
type=gha uses the GitHub Actions cache backend — no external cache service needed.
Common Mistakes
| Mistake | Fix |
|---|---|
packages: write missing for GHCR |
Add to permissions: block |
| Docker Hub rate limits | Use authenticated pulls with docker/login-action |
| Large image size | Use multi-stage builds and .dockerignore |
| No build cache | Add cache-from/cache-to with type=gha |
Quick Reference
| Registry | Login Action |
|---|---|
| GHCR | docker/login-action@v3 with registry: ghcr.io |
| Docker Hub | docker/login-action@v3 (no registry param) |
| ECR | aws-actions/amazon-ecr-login@v2 |
| ACR | azure/docker-login@v2 |
| Build | docker/build-push-action@v6 |
| Tags | docker/metadata-action@v5 |
| Multi-arch | docker/setup-qemu-action@v3 + docker/setup-buildx-action@v3 |
← Previous: Deploy to Kubernetes
Next: Deployment Protection →