World map

 

BM: Baca dalam Bahasa Melayu

World C2: Container Pipelines

Push to GHCR

You will learn: to push images to GitHub's registry with the job's own token.

Checked with GitHub Actions 2026-10 on 31 Oct 2026

The problem

Pick an event. Press Run and watch the line.

A push to main builds the image, then the push to ghcr.io is denied. The build station turns red.

What happened on GitHub

Workflow file .github/workflows/publish.yml

name: Publish
on:
push:
branches: [main]
permissions:
contents: read
jobs:
image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v7
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

The line

Push to main · main

Press Run. The pack is built, then stopped at the freezer door: denied: permission_denied: write_package. Plain words: this job’s key can’t put packs in.

Watch

Tap the line that hands over the job's pass.

0 of 1 found

GHCR: GitHub Container Registry (ghcr.io): GitHub's own shop freezer for images. (ghcr.io) is GitHub’s own shop freezer. The job logs in with GITHUB_TOKEN. It’s a pass that ends when the job ends.

Try it

What does this job’s pass need? Give it the least.

Drag a card into a box. Or tap the card, then tap the box.

      Try it

      Now fix the yellow lines. Pick the permissions, then press Run.

      The line is red. Fix the yellow lines, then run again.

      What happened on GitHub

      Workflow file .github/workflows/publish.yml

      name: Publish
      on:
      push:
      branches: [main]
      permissions:
      contents: read
      jobs:
      image:
      runs-on: ubuntu-latest
      steps:
      - uses: actions/checkout@v7
      - uses: docker/setup-buildx-action@v4
      - uses: docker/login-action@v4
      with:
      registry: ghcr.io
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v7
      with:
      push: true
      tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
      

      Yellow: lines 5–6. You can change these.

      Pick a fix

      The line

      Push to main · main

      Predict

      Mei opens a PR from her fork. The workflow pushes on PRs too. What happens?

      Pick one answer.

      Check

      Build the command that pulls version 1.2.0 from GHCR.

      Tap the pieces in the right order.

      …

      You did it!

      You can now push images to GHCR with only the keys needed.

      Go deeper (optional)

      A package pushed with GITHUB_TOKEN takes its repo’s visibility and access rules. Owner names with capitals break ghcr.io/${{ github.repository }}. metadata-action makes image names lowercase for you.

      Real rep (optional), in a public practice repo:

      Real mission

      0 of 4 steps done · Your ticks are saved.