From 89f738885c0708f02a0fb22708a922b2daf9ec96 Mon Sep 17 00:00:00 2001 From: CodeGit Date: Fri, 4 Sep 2026 07:18:52 +0100 Subject: [PATCH] docs: fix Forgejo runner setup gaps in stage 3 step 6 - Distinguish the runner registration token from FORGEJO_TOKEN explicitly (easy to mix up, causes a confusing "registration token not found" error) - Split register/daemon into two commands: register is one-shot and exits, running only it under --restart unless-stopped silently loops forever instead of ever listening for a job - Add --userns=keep-id, needed so the container can open the rootless Podman socket (owned by k8s's host UID, not the container's remapped one) - Note that / are placeholders to replace, not literal syntax, since bash reads a bare as redirection Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Y4YNpuC2bgT224suQLLJ7B --- docs/03-flux.md | 68 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/docs/03-flux.md b/docs/03-flux.md index b260ebd..74db272 100644 --- a/docs/03-flux.md +++ b/docs/03-flux.md @@ -302,22 +302,67 @@ doesn't share a blast radius with the cluster. echo $XDG_RUNTIME_DIR # note this path, e.g. /run/user/1001 ``` 2. Instance admin: `Site Administration → Actions → Runners`, confirm - Actions is enabled. + Actions is enabled. `Site Administration` is a top-level menu only + visible to instance admin accounts (not just repo owners) — click your + profile avatar (top-right of any page) and look for it in the dropdown; + if it's not there, the account you're logged in as isn't an instance + admin. Inside, it's a left-hand sidebar (Dashboard, Users, + Organizations, Repositories, Packages, Actions, Config, Notices, + Monitor, ...) — click `Actions` there for the runners view. 3. Repo: `Settings → Actions → Runners → Create new runner`, copy the - registration token. + registration token. **This token is unrelated to `FORGEJO_TOKEN` in step + 5 below** — easy to mix up since both are "a Forgejo token," but they're + different things from different pages: this one is single-purpose, + scoped to registering exactly one runner, generated on this + `Actions → Runners` page. `FORGEJO_TOKEN` (step 5) is a personal access + token from `Settings → Applications` on your own account, scoped to + `package:write`, used by CI to push images — it has nothing to do with + runner registration. If you paste `FORGEJO_TOKEN` into step 4 below by + mistake, registration fails with `invalid_argument: runner registration + token not found`. 4. Register and run the runner as a rootless Podman container, pointed at - the Podman socket from step 1 instead of docker.sock: + the Podman socket from step 1 instead of docker.sock. This is two + separate commands, not one — `forgejo-runner register` is a one-shot + action that talks to Forgejo once and exits; the thing that actually + stays running and picks up jobs is a separate `forgejo-runner daemon` + process. Running only `register` under `--restart unless-stopped` (an + easy mistake, since it looks like a normal long-running container + command) makes it silently loop: register succeeds, the container exits, + Podman restarts it, it registers again, forever — never once actually + listening for a job. Both commands also need `--userns=keep-id`: + rootless Podman's socket file is owned by `k8s`'s own UID on the host, + but a container's "root" user normally maps to a *different*, + subuid-remapped UID under the hood — `--userns=keep-id` makes the + container's user *be* `k8s`'s actual UID instead, so it can open a + socket file owned by that UID. Without it, the daemon fails with + `permission denied` connecting to the socket. ```sh # still as k8s podman volume create forgejo-runner-data - podman run -d --name forgejo-runner --restart unless-stopped \ - -e DOCKER_HOST="unix://$XDG_RUNTIME_DIR/podman/podman.sock" \ - -v "$XDG_RUNTIME_DIR/podman/podman.sock:$XDG_RUNTIME_DIR/podman/podman.sock" \ + + # one-shot: register, then exits (--rm, not -d) + podman run --rm --userns=keep-id \ -v forgejo-runner-data:/data \ code.forgejo.org/forgejo/runner:6 \ forgejo-runner register --no-interactive \ --instance https://git.boglabob.com \ --token --labels docker:docker://node:20-bookworm + + # persistent: the actual daemon that listens for jobs + podman run -d --name forgejo-runner --restart unless-stopped \ + --userns=keep-id \ + -e DOCKER_HOST="unix://$XDG_RUNTIME_DIR/podman/podman.sock" \ + -v "$XDG_RUNTIME_DIR/podman/podman.sock:$XDG_RUNTIME_DIR/podman/podman.sock" \ + -v forgejo-runner-data:/data \ + code.forgejo.org/forgejo/runner:6 \ + forgejo-runner daemon + ``` + Confirm it's actually stable rather than looping — `podman ps --filter + name=forgejo-runner` should show one steadily increasing uptime, not a + container repeatedly restarting seconds after creation: + ```sh + podman ps --filter name=forgejo-runner + podman logs --tail 20 forgejo-runner ``` The registered runner picks up both workflows in `.forgejo/workflows/` — `terraform.yml`'s `container:` image (stage 4) and @@ -325,12 +370,19 @@ doesn't share a blast radius with the cluster. that same rootless Podman socket. 5. Repo `Settings → Secrets and Variables → Actions`, add: - Secret `FORGEJO_TOKEN` — a personal access token (`Settings → Applications` - on your Forgejo user, scope `package:write`) used to push images. + on your Forgejo user, scope `package:write`) used to push images. See + the callout on step 3 above — this is a different token from the + runner registration one, despite both living under "Forgejo tokens." - Variable `FORGEJO_USER`, `FORGEJO_ORG` — your Forgejo username/org. If the `hello-app` package ends up private (Forgejo package visibility follows repo visibility by default), create the cluster-side pull secret -and uncomment the `imagePullSecrets` line in `apps/hello-app/deployment.yaml`: +and uncomment the `imagePullSecrets` line in `apps/hello-app/deployment.yaml`. +``/`` below are placeholders to replace with +your actual values, not literal syntax — bash reads a bare `` as +input redirection, so pasting them unreplaced fails with a confusing +`syntax error near unexpected token 'newline''` instead of a helpful +message: ```sh kubectl -n hello-app create secret docker-registry forgejo-registry \