- 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>
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.
Path A: Docker Compose (recommended)
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
-
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.)
-
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-interactiveThis writes
.runner(registration file) andconfig.ymlinto the current directory. -
Start the daemon (Docker:
docker compose up -d; binary:forgejo-runner daemon). -
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-latestneeds a runner registered with that label). - Check the runner logs:
docker logs forgejo-runneror 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.sockwhich 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.