# Forgejo Runner Setup ## Obtaining the Registration Token 1. Log in to the Forgejo instance at `https://forgejo.contrapeso.xyz` 2. Go to **Site Administration** > **Actions** > **Runners** 3. Click **Create new runner** 4. Copy the registration token ## Configuring the Token Paste the token into `ansible/infra_secrets.yml`: ```yaml forgejo_runner_registration_token: "YOUR_TOKEN_HERE" ``` ## Running the Playbook ```bash ansible-playbook ansible/services/forgejo-runner/deploy_forgejo_runner_playbook.yml ``` ## Verifying 1. On the VM: `systemctl status forgejo-runner` should show active 2. In Forgejo: **Site Administration** > **Actions** > **Runners** should show the runner as online 3. ~~In Uptime Kuma: the `forgejo-runner-healthcheck` push monitor should be receiving pings~~ *(Uptime Kuma was decommissioned 2026-09-11 — this check no longer applies. The healthcheck timer still runs on the host but pushes nowhere. See `archive/uptime_kuma/`.)* ## Docker in CI jobs Jobs get their own Docker daemon (a `docker:dind` sidecar), not this host's. Enabled by `forgejo_runner_dind_enabled` in the deploy playbook; the mechanism, the trade-offs and how to turn it off are in `ansible/roles/forgejo_runner/README.md`. A workflow needs no special configuration — `DOCKER_HOST` is already set in every job container: ```yaml jobs: build: runs-on: docker steps: - uses: actions/checkout@v7 - run: docker build -t my-app . - run: docker compose up -d --wait ``` Verifying after a deploy: 1. `systemctl status forgejo-dind` — active, and `docker -H tcp://127.0.0.1:2376 version` answers from the box. 2. `docker ps` on the host shows `forgejo-dind` and, during a run, **no** job containers: they are inside dind now. `docker exec forgejo-dind docker ps` shows those. 3. A workflow step running `docker version` reports the dind daemon. One caveat worth knowing before writing an end-to-end job: a `docker compose` bind mount resolves on the dind filesystem, not in the job container, so a compose file that mounts the checked-out repo will not see it. Named volumes and `build:` contexts work normally.