Forgejo Runner configurations, running with root-less Podman
Find a file
2025-08-23 22:21:16 -04:00
.gitignore Initial commit 2025-08-23 10:48:41 -04:00
docker-compose.yml Add register comment 2025-08-23 22:15:21 -04:00
LICENSE Add LICENSE 2025-08-23 13:43:31 -04:00
README.md Update README.md 2025-08-23 22:21:16 -04:00

Forgejo Runner with Podman

My configurations for running a Forgejo Runner with root-less Podman Compose. This configuration enables Actions to build container images using buildah.

architecture-beta
    group host(cloud)[Runner Host Userspace]
    group runner(cloud)[Forgejo Runner Rootless Container] in host
    group runtime(cloud)[Podman Runtime Rootless Container] in host

    service forgejo(server)[Forgejo Server]
    service daemon(server)[Runner Daemon] in runner
    service build1(server)[Build Privileged Container] in runtime
    service build2(server)[Build Privileged Container] in runtime

    forgejo:R --> L:daemon
    daemon:R --> L:build1
    daemon:R --> L:build2

Set-up

Install podman and podman-compose:

sudo apt-get update && sudo apt-get install -y podman podman-compose

Create the data directories (/data) for persisting Forgejo runner configurations and cache:

sudo mkdir -p /data/.cache /data/.config
sudo touch /data/.runner

sudo chown -R $UID:$UID /data
sudo chmod -R 700 /data

Clone this repository:

git clone https://git.poire.dev/aramperes/forgejo-runner-podman.git

For the first-time set-up, you will need to stop the Forgejo Runner from starting to register with the Forgejo server.

# vim docker-compose.yml

- command: /bin/sh -c "sleep 5; forgejo-runner daemon -c .config/config.yml"
- # command: /bin/sh -c "while : ; do sleep 1 ; done ;"
+ # command: /bin/sh -c "sleep 5; forgejo-runner daemon -c .config/config.yml"
+ command: /bin/sh -c "while : ; do sleep 1 ; done ;"

Start the services:

podman-compose up -d

Confirm the containers are running. This might take a few seconds.

podman ps
# CONTAINER ID  IMAGE                              COMMAND               CREATED         STATUS         PORTS       NAMES
# 71cb0d2af329  quay.io/podman/stable:latest       podman system ser...  12 minutes ago  Up 12 minutes              podman-runtime
# 9b29fcb10113  data.forgejo.org/forgejo/runner:9  /bin/sh -c while ...  12 minutes ago  Up 12 minutes              forgejo-runner

Register the Runner

On your Forgejo server's Site administration page, go to Actions, Runners. Click Create a new runner and copy the token.

Back on your Forgejo Runner host, run:

podman exec -it forgejo-runner /bin/sh

# Run inside the container and follow the instructions:
# (I recommend setting the label 'docker')
forgejo-runner register

# Confirm the .runner file has been written to:
cat .runner

# Write out default configurations:
forgejo-runner generate-config > .config/config.yml

exit

For building containers, you will need to tweak the runner's configurations to create privileged containers and avoid creating a nested network stack. Don't worry, this is still sandboxed inside the podman-runtime container.

# sudo vim /data/.config/config.yml

container:
-  network: ""
+  network: host
-  privileged: false
+  privileged: true

Revert the runner's command to launch the daemon:

# vim docker-compose.yml

- # command: /bin/sh -c "sleep 5; forgejo-runner daemon -c .config/config.yml"
- command: /bin/sh -c "while : ; do sleep 1 ; done ;"
+ command: /bin/sh -c "sleep 5; forgejo-runner daemon -c .config/config.yml"
+ # command: /bin/sh -c "while : ; do sleep 1 ; done ;"

Update the services:

podman-compose up -d

Now, in the Forgejo server Runners page, you should see your new runner as "Idle".

Example Action: build and push an image

Note, secrets.PACKAGE_TOKEN is a Forgejo Personal Access Token (PAT) with write-permissions to the Packages function. This has to be created manually because the automatic token FORGEJO_TOKEN does not have this permission. Track this feature request.

# .forgejo/workflows/image.yaml

on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: docker
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Extract the tag
        id: extract_tag
        run: echo "::set-output name=tag::$(echo ${{ forge.sha }} | cut -c1-10)"
      - name: Install Buildah and Podman
        run: apt-get update && apt-get install -y buildah podman
      - name: Buildah Build
        id: build-image
        uses: redhat-actions/buildah-build@v2
        with:
          image: aramperes/imagename
          tags: ${{ steps.extract_tag.outputs.tag }}
          context: .
          containerfiles: ./Dockerfile
      - name: Push to Registry
        uses: https://github.com/redhat-actions/push-to-registry@v2
        with:
          image: ${{ steps.build-image.outputs.image }}
          tags: ${{ steps.build-image.outputs.tags }}
          registry: git.poire.dev
          username: ${{ env.FORGEJO_ACTOR }}
          password: ${{ secrets.PACKAGE_TOKEN }}