# 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`: ```yaml 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`: ```bash 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: ```bash forgejo-runner register \ --instance https://forgejo.sourcegate.online \ --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) ```ini [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.