--- /dev/null
+name: Docker Publish (GHCR)
+
+on:
+ push:
+ tags:
+ - 'v*' # e.g. v1.2.3
+
+permissions:
+ contents: read
+ packages: write
+ # id-token: write # <- uncomment if you enable provenance/SBOM
+
+env:
+ # Lowercase repo name for GHCR robustness
+ IMAGE_REGISTRY: ghcr.io
+ IMAGE_OWNER: ${{ github.repository_owner }}
+ IMAGE_REPO: ${{ github.event.repository.name }}
+
+jobs:
+ build-and-push:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Login to GHCR
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ # Optional but recommended: generate tags & labels from Git tag using docker/metadata-action
+ - name: Extract Docker metadata
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: |
+ ghcr.io/${{ env.IMAGE_OWNER }}/${{ env.IMAGE_REPO }}
+ tags: |
+ type=ref,event=tag
+ type=raw,value=latest
+ flavor: |
+ latest=true
+ labels: |
+ org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
+ org.opencontainers.image.revision=${{ github.sha }}
+ org.opencontainers.image.created=${{ github.run_started_at }}
+
+ - name: Build & Push image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ./Dockerfile
+ push: true
+ # platforms: linux/amd64,linux/arm64 # <- enable if you want multi-arch
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ # provenance: true # <- enable if you granted id-token: write