furtka/docs/runner-setup.md
Daniel Maksymilian Syrnicki 7759574481 docs: add changelog, contributor guide, release process, and runner setup
- CHANGELOG.md: Keep-a-Changelog format, [26.0-alpha] entry covering
  everything shipped so far (installer webapp, drive scoring, base
  archinstall config, wireframes, competitor analysis, wizard flow spec)
- CONTRIBUTING.md: dev setup, conventional commit format, code style
- RELEASING.md: calendar versioning rules (YY.N-stage, no "v" prefix)
  and the release workflow (bump changelog, commit, tag, push, create
  Forgejo Release)
- docs/runner-setup.md: install + register a forgejo-runner so the
  upcoming CI workflow actually executes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:23:48 +02:00

3.8 KiB

Forgejo Runner Setup

How to stand up a forgejo-runner so the CI workflow in .forgejo/workflows/ci.yml actually executes on every push.

The runner is a long-running daemon that polls the Forgejo instance for queued jobs and runs them in Docker containers.

Choosing a host

Option Good for Trade-off
Dedicated VPS Production-ish CI that runs even when you're offline Costs a few €/month; one more machine to maintain
Home server / NAS Free; plenty of capacity CI blocked if home network / power drops
Local dev machine Quick to set up, fast runs CI only works while the machine is on

Recommendation for now: home server or a cheap VPS. Don't use a laptop that suspends.

Install

Pick either the binary or the Docker container path. Docker is easier to upgrade.

On the chosen host, create ~/forgejo-runner/compose.yml:

services:
  runner:
    image: code.forgejo.org/forgejo/runner:6
    container_name: forgejo-runner
    restart: unless-stopped
    environment:
      - CONFIG_FILE=/data/config.yml
    volumes:
      - ./data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - docker-in-docker
    command: /bin/sh -c "sleep 5; forgejo-runner daemon"

  docker-in-docker:
    image: docker:dind
    container_name: forgejo-runner-dind
    restart: unless-stopped
    privileged: true
    environment:
      - DOCKER_TLS_CERTDIR=
    command: dockerd -H tcp://0.0.0.0:2375 --tls=false

Path B: Binary

Download the latest release from https://code.forgejo.org/forgejo/runner/releases and drop it somewhere in $PATH:

wget https://code.forgejo.org/forgejo/runner/releases/download/v6.0.0/forgejo-runner-6.0.0-linux-amd64
chmod +x forgejo-runner-6.0.0-linux-amd64
sudo mv forgejo-runner-6.0.0-linux-amd64 /usr/local/bin/forgejo-runner

Register

  1. In the Forgejo web UI: go to Site Administration → Actions → Runners → Create new Runner. Copy the registration token. (For a repo-scoped runner instead, use Repo Settings → Actions → Runners.)

  2. Register from the runner host:

    forgejo-runner register \
      --instance https://forgejo.sourcegate.online \
      --token <TOKEN> \
      --name homebase-runner-1 \
      --labels docker,ubuntu-latest,self-hosted \
      --no-interactive
    

    This writes .runner (registration file) and config.yml into the current directory.

  3. Start the daemon (Docker: docker compose up -d; binary: forgejo-runner daemon).

  4. Verify the runner shows up as Idle in Forgejo's admin Runners page.

First CI run

Push any commit; the Actions tab on the repo should show the workflow running. If nothing happens:

  • Confirm the runner is online (Forgejo admin → Actions → Runners).
  • Check the workflow has labels that match the runner (runs-on: ubuntu-latest needs a runner registered with that label).
  • Check the runner logs: docker logs forgejo-runner or the systemd journal.

Systemd unit (for the binary path)

[Unit]
Description=Forgejo Actions Runner
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/local/bin/forgejo-runner daemon
WorkingDirectory=/var/lib/forgejo-runner
User=forgejo-runner
Restart=on-failure

[Install]
WantedBy=multi-user.target

Save as /etc/systemd/system/forgejo-runner.service, then sudo systemctl enable --now forgejo-runner.

Security notes

  • The runner mounts /var/run/docker.sock which gives it root-equivalent access to the host. Run it on a machine you trust and nothing sensitive.
  • Registration tokens are one-shot; a stolen token can't re-register after the runner is live.
  • Prefer repo-scoped runners over instance-wide if you're sharing the runner with other repos you don't control.