Skip to guide
Help center

Build an image in GitHub Actions and publish it to GHCR

Build your Dockerfile in GitHub Actions, publish the image to GHCR for the architecture of your cluster and deploy each new version.

Why build outside Tenkai

With a Git source, Tenkai builds on your cluster, with the CPU and memory of your servers, and the repository must be public today. Building in GitHub Actions moves the build to GitHub, and Tenkai pulls the image from the GitHub Container Registry, GHCR. This works for private code too.

You need a repository with a working Dockerfile, such as the one of the Node.js or PHP guide, and the CPU architecture of your cluster: x86-64 or arm64.

Add the workflow

Create .github/workflows/publish-image.yml:

name: Publish image

on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      packages: write
    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 }}

      - id: meta
        uses: docker/metadata-action@v6
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=ref,event=branch
            type=sha

      - uses: docker/build-push-action@v7
        with:
          context: .
          platforms: linux/amd64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Each push to main publishes the image as ghcr.io/<owner>/<repository>, tagged main, which moves to each build, and sha- followed by the short commit SHA. You create no token: packages: write lets the workflow's GITHUB_TOKEN publish.

Push the workflow and follow the run in the Actions tab. The image then appears under Packages on the repository page.

Build for the architecture of your cluster

Tenkai refuses an image without a variant for the CPU architecture of your servers. The workflow above builds for x86-64. For an arm64 cluster, change two lines:

runs-on: ubuntu-24.04-arm
platforms: linux/arm64

Building arm64 on an x86-64 runner works through emulation, but several times slower.

Let Tenkai pull the image

GitHub makes a new package private, even for a public repository. Either:

  • Make the package public. Open the package, then Package settings, Change visibility and Public. Anyone can then pull it, so check that the image holds no secrets. A public package of an organization cannot become private again.
  • Keep it private. Create a personal access token (classic) with only the read:packages scope, and add it as a GHCR credential in your account. GHCR does not accept fine-grained tokens. Pull a private GHCR image explains which account should own it.

Create the resource

  1. In the project, choose Add resource, then Application.
  2. Choose Web application and Container image as the build source.
  3. Enter the image reference with its moving tag, such as ghcr.io/acme/hello:main.
  4. For a private package, choose a GHCR credential that Can pull it.
  5. Create the resource.

Set the variables your application needs, then choose Deploy. Wait for an active release and open its default route.

Deploy a new version

Push to main, wait for the workflow to finish, then choose Deploy on the resource. A deployment started earlier deploys the previous image. To deploy from the workflow, call the deploy hook of the resource in a last step.

Each deployment records the digest that main pointed to, so a rollback brings back that exact image. To pin a resource to one build, use its digest as the image reference, such as ghcr.io/acme/hello@sha256:….

If the deployment fails

Read the message of the failed deployment on the resource's overview tab.

  • The tag does not exist: check that the workflow succeeded and that the reference uses the lowercase name of the package.
  • The image has no variant for the architecture of the server: build for it.
  • Tenkai cannot pull the image: make the package public, or link a GHCR credential that can pull it from Image access in Configuration.

Troubleshooting lists the other source checks.