Overall Flow
CODE
git push → GitHub Actions trigger
→ Checkout code
→ Build Docker image
→ Push to registry (GHCR / Docker Hub)
→ docker pull + restart on the serverDeploying to GHCR (GitHub Container Registry)
YAML
# .github/workflows/docker-build.yml
name: Docker Build & Push
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix=sha-
type=semver,pattern={{version}}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=maxAutomatic Server Deployment After Build
YAML
- name: Deploy to server
if: github.ref == 'refs/heads/main'
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull ghcr.io/${{ github.repository }}:main
docker compose -f /opt/app/docker-compose.yml up -d app
docker image prune -fConfiguring Secrets
GitHub repository → Settings → Secrets and variables → Actions:
| Secret name | Value |
|---|---|
SERVER_HOST | Server IP or domain |
SERVER_USER | SSH username |
SSH_PRIVATE_KEY | SSH private key (-----BEGIN OPENSSH PRIVATE KEY----- ...) |
GITHUB_TOKEN is provided automatically by Actions.
Multi-architecture Builds (ARM Support)
YAML
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Build and push (multi-arch)
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}Use this when you need to support ARM servers (AWS Graviton, Raspberry Pi) and x86 servers at the same time.
Speeding Up Builds with Caching
GitHub Actions cache is used with just the cache-from: type=gha / cache-to: type=gha,mode=max settings. Unchanged layers are not rebuilt, which significantly reduces build time.
Editorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Docker documentation ↗Git documentation ↗
Questions & answers
Ask a question about this guide. We'll review and reply.