feat(forgejo): Mac mini Actions runner toolkit + server-side status monitor - #51
Merged
Conversation
…ecar The Mac mini Forgejo Actions runner had no docs and broke after the server moved off ollie-server:3300 to its own Tailscale node (forgejo:3000) without the runner config being updated. macOS/forgejo-runner/: install/verify/run scripts (binary built from source — Forgejo ships no macOS builds), config + LaunchAgent templates, and a README covering setup and the connection-refused failure mode. linux-server/forgejo/: rewrite docker-compose.yml to the per-service Tailscale sidecar model (own tailnet device, no host ports, :3000, SSH on 22) matching the live deployment; reconcile the now-stale :3300/:2222 references in the homepage widget, post-install.md, and README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read the registration token with `read -rs` so it no longer echoes to the terminal/scrollback, and emit the swallowed newline. Remove the unused check() helper in verify.sh — every check inlines its own failure count. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hardcoded tailnet in DEFAULT_INSTANCE_URL with a placeholder and source an optional .env (gitignored) for the real value; add .env.example (quoted so the placeholder isn't parsed as a shell redirection when sourced). Scrub the real hostname from the README troubleshooting note and the example config's connection name/comment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document that the repo is public: keep identifying/secret values (tailnet names, hostnames, IPs, usernames, emails, tokens, personal paths) out of tracked files, use gitignored .env + committed .env.example placeholders, and prefer placeholders in docs/configs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the real hostname, LAN IP, and tailnet name with the repo's <hostname>/<server-ip>/<tailnet> placeholders across the server README, post-install guide, homepage .env.example, and NPM compose comment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adopt main's HTTPS-via-tailscale-serve forgejo sidecar (forgejo-ts,
ROOT_URL=https://${FORGEJO_DOMAIN}/), superseding this branch's earlier
HTTP-on-:3000 forgejo sidecar. Conflicts resolved:
- linux-server/forgejo/{docker-compose.yml,.env.example}: took main
- linux-server/homepage/config/services.yaml: took main (HTTPS forgejo card)
- linux-server/{README,post-install}.md: kept the fully-redacted <hostname>
form of the tailscale-cert example
Follow-up commit aligns the runner tooling + forgejo doc sections (still
referencing :3000) to the HTTPS endpoint.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After merging main, Forgejo is served over HTTPS by a tailscale serve sidecar (ROOT_URL=https://forgejo.<tailnet>.ts.net/), not plain HTTP on :3000. Repoint the Mac mini runner tooling and the server docs accordingly: - runner: FORGEJO_INSTANCE_URL -> https://forgejo.<tailnet>.ts.net (no port), updated lib.sh default, .env.example, README diagram/troubleshooting, config example, install.sh usage, verify.sh fix hint - server docs: forgejo web UI URLs in README.md and post-install.md Git SSH stays on :22 (unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a host timer that asks Forgejo's runners API whether the Mac mini Actions
runner is connected (status idle/active = up, offline/absent = down) and
surfaces it three ways, reusing the backup feature's patterns:
- homepage 'forgejo-runner' customapi card (JSON served by a loopback nginx
added to forgejo/docker-compose.yml on 127.0.0.1:8098)
- Uptime Kuma push (KUMA_PUSH_URL)
- ntfy alert on down/recovery transitions only
runner-status.sh parses the API defensively (bare array or {runners|entries}
wrapper), falls back to 'down' when Forgejo is unreachable, and is driven by
forgejo-runner-status.{service,timer} (every 2 min). Config lives in
forgejo/.env (token + RUNNER_NAME + optional Kuma/ntfy); FORGEJO_DOMAIN is now
quoted there since the script sources the file. Runtime JSON is gitignored.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reorder services.yaml groups to Management, Network, Storage, NAS. Pure block move — no service entries or widgets changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…root policy - Set fence.allow_local_overrides: true in the active policy so a project can ship an additive .railguard.local.yaml (existing railguard feature; only ADDs to allowed_paths, never weakens denies — grants nothing on its own). - Gitignore the stray repo-root railguard.yaml (a `railguard init` starter); the real policy lives in agentic-ai/Claude/railguard.yaml. Anchored so only the root file is ignored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documents and tools the Mac mini Forgejo Actions runner, and adds a server-side
way to see whether it's up. Along the way this branch merges
main(adoptingits HTTPS-via-
tailscale serveForgejo sidecar), hardens the runner scripts,and adds a Privacy & Security policy plus an identifier scrub since the repo is
public.
The runner originally broke after the Forgejo server moved to its own Tailscale
node and the runner kept dialing the old endpoint. This branch makes the whole
path consistent: Forgejo is reached at
https://forgejo.<tailnet>.ts.neteverywhere (runner config, server compose, docs).
Changes
Mac mini runner toolkit —
macOS/forgejo-runner/(new)install.sh/verify.sh/run.sh/lib.sh— build from source (Forgejoships no macOS binaries), register, health-check, and control the LaunchAgent.
net.forgejo.runner.plist.template, token-freeforgejo-runner-config.example.yml,and a README covering setup and the
connection refusedfailure mode..env(.env.exampleprovided); theregistration token is read with
read -rs(no echo); dead code removed.Server-side runner status monitor —
linux-server/forgejo/(new)runner-status.shasks Forgejo's runners API whether the Mac mini runner isconnected (
idle/active= up,offline/absent/unreachable = down) andsurfaces it three ways:
added to
docker-compose.ymlon127.0.0.1:8098),KUMA_PUSH_URL),forgejo-runner-status.{service,timer}drive it every 2 minutes.forgejo/.env(token +RUNNER_NAME+ optional Kuma/ntfy); runtimeJSON is gitignored.
Merge of
main+ HTTPS alignmenttailscale serveForgejo sidecar (forgejo-ts,ROOT_URL=https://${FORGEJO_DOMAIN}/), superseding this branch's earlierHTTP-on-
:3000sidecar.http://…:3000tohttps://forgejo.<tailnet>.ts.net(Git SSH stays on:22).Privacy & Security
CLAUDE.md: repo is public — keepidentifying/secret values out of tracked files, use gitignored
.env+committed
.env.exampleplaceholders.<hostname>/<server-ip>/<tailnet>across the server configs and docs.Homepage
Validation
shellcheck --severity=warningclean on all shell;runner-status.shparsingtested against bare-array /
{runners|entries}-wrapper / absent / unreachableresponses; YAML files parse.
docker compose configinlinux-server/forgejo/;url:tohttps://forgejo.<tailnet>.ts.net, thenbash macOS/forgejo-runner/run.sh restart;(
/api/v1/admin/actions/runners) and is overridable viaFORGEJO_RUNNER_API_URLif your token is org/repo-scoped.🤖 Generated with Claude Code