How to Publish a Docker Image to GHCR With GitHub Actions
Log in to ghcr.io with the built-in token and push with docker/build-push-action, tagging the image from docker/metadata-action.
Grant packages: write, log in to ghcr.io with GITHUB_TOKEN, generate tags with docker/metadata-action, then build and push with docker/build-push-action. No personal token is needed for same-repo packages.
Steps
- Add
permissions: packages: writeandcontents: read. - Log in to
ghcr.iousingdocker/login-actionwithGITHUB_TOKEN. - Compute tags with
docker/metadata-action. - Build and push with
docker/build-push-action.
Workflow
.github/workflows/publish.yml
permissions:
contents: read
packages: write
jobs:
publish:
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 }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
- uses: docker/build-push-action@v6
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}Common pitfalls
- Without
packages: writethe push fails with "denied: permission_denied". - A new package is private by default; link it to the repo and set visibility, or pulls 404 for others.
- The image name must be lowercase;
github.repositorywith an uppercase owner breaks the push, so lowercase it.
Related guides
How to Deploy a Container to Amazon ECS With GitHub ActionsBuild and push an image to ECR then deploy to Amazon ECS from GitHub Actions, rendering a new task definition…
How to Deploy a Helm Chart to Kubernetes With GitHub ActionsDeploy a Helm chart to a Kubernetes cluster from GitHub Actions using azure/setup-helm and helm upgrade --ins…