Commit f2bffdcbb5

f2bffdcbb58d25feff7df76cef83edf96df69e40

parent: cae1d071e4

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-02 02:56 UTC

Admin: runners, healthz, monitor backup ages, gc --lfs, backup --verify

Ref krz/gitbay#75 #76 #77 #78 #79 #80

Layout: unified · split

Admin.org +24 −4
@@ -231,6 +231,7 @@ gitbayd admin stats [--json] # counts, database size, per-repo disk
231ssh git@<host> admin stats [--json] # the same, from an admin session 231ssh git@<host> admin stats [--json] # the same, from an admin session
232gitbayd admin gc [--repo owner/name] # git gc: repack and prune; per-repo sizes 232gitbayd admin gc [--repo owner/name] # git gc: repack and prune; per-repo sizes
233gitbayd admin gc --aggressive # thorough repack; slow, rarely needed 233gitbayd admin gc --aggressive # thorough repack; slow, rarely needed
234gitbayd admin gc --lfs # also drop LFS objects no pointer names (older than a day)
234#+end_src 235#+end_src
235 236
236=deploy/cloud-init.yaml= ships a =gitbay-gc.timer= that runs =admin gc= 237=deploy/cloud-init.yaml= ships a =gitbay-gc.timer= that runs =admin gc=
@@ -242,6 +243,7 @@ import is worthwhile.
242 243
243#+begin_src sh 244#+begin_src sh
244gitbayd admin backup --out /var/backups/gitbay/backup.tar.gz 245gitbayd admin backup --out /var/backups/gitbay/backup.tar.gz
246gitbayd admin backup --verify /var/backups/gitbay/backup.tar.gz # read it back
245#+end_src 247#+end_src
246 248
247One archive: a consistent SQLite snapshot (taken *before* the 249One archive: a consistent SQLite snapshot (taken *before* the
@@ -250,6 +252,11 @@ archive missed), every repository, and the SSH host keys. Excluded:
250hook socket, regenerated hook scripts, WAL files. Safe to run against a 252hook socket, regenerated hook scripts, WAL files. Safe to run against a
251live daemon. 253live daemon.
252 254
255=--verify= reads an archive back: the snapshot must pass SQLite's
256integrity check, and every repository the snapshot names must be in the
257archive. A database-only archive is checked for integrity and says so.
258Exit is non-zero on damage or a missing repository.
259
253Restore: extract into an empty directory, point =server.root= at it, 260Restore: extract into an empty directory, point =server.root= at it,
254start gitbayd. Host keys are preserved, so clients keep their 261start gitbayd. Host keys are preserved, so clients keep their
255known_hosts entries; hooks regenerate at startup. 262known_hosts entries; hooks regenerate at startup.
@@ -319,6 +326,12 @@ the runner on the server itself. The scoping is what the runner asks for,
319not an ACL the server holds over it: a runner account is admin by 326not an ACL the server holds over it: a runner account is admin by
320necessity, so the boundary is you choosing how to start it. 327necessity, so the boundary is you choosing how to start it.
321 328
329=gitbay dashboard= and =ssh git@<host> admin runners= list every account
330that has polled as a runner: when it last polled, the =-repos= scope it
331asked for, and the build it holds. A build a runner claimed and never
332reported is failed by the scheduler's minute tick, whether or not any
333runner is still alive.
334
322Instance admin on the runner account only authorizes the claim/report 335Instance admin on the runner account only authorizes the claim/report
323protocol; it grants no repo access. A build that pushes back — a pages 336protocol; it grants no repo access. A build that pushes back — a pages
324deploy, an archive publish, an automated MR branch — needs an explicit 337deploy, an archive publish, an automated MR branch — needs an explicit
@@ -374,10 +387,17 @@ trusts and refuses to do. Operational checklist:
374- *Admin sshd (2222)* is throttled by =MaxStartups=/=MaxAuthTries= and 387- *Admin sshd (2222)* is throttled by =MaxStartups=/=MaxAuthTries= and
375 watched by =fail2ban=; gitbayd's own port 22 is throttled by 388 watched by =fail2ban=; gitbayd's own port 22 is throttled by
376 =limits.ssh_auth_rate= (auth failures per IP per minute). 389 =limits.ssh_auth_rate= (auth failures per IP per minute).
377- *Monitoring.* =gitbay-monitor.timer= posts disk/service/cert status 390- *Monitoring.* =gitbay-monitor.timer= writes a reading hourly to
378 hourly to the webhook URL in =/etc/gitbay/monitor.url= (create the 391journald and, when =/etc/gitbay/monitor.url= exists, posts it to that
379 file to enable; absent = silent). Alerts fire on a stopped service or 392webhook: disk, service, the daemon's own =/healthz= answer, certificate
380 disk ≥ 85%. 393expiry, and the age of the newest full backup and database snapshot.
394It exits non-zero on an alert so the unit shows in =systemctl
395--failed=: a stopped service, =/healthz= not answering =ok=, disk ≥ 85%,
396a certificate under 21 days, a full backup over 25 hours old, or a
397database snapshot over 2 hours old.
398
399=GET /healthz= is unauthenticated and cache-free: whether the database
400answers and which commit serves, 503 when it does not.
381- *Database.* =gitbay.db= and its WAL live under =/var/lib/gitbay= (mode 401- *Database.* =gitbay.db= and its WAL live under =/var/lib/gitbay= (mode
382 0750, owned by =gitbay=). The nightly archive plus provider snapshots 402 0750, owned by =gitbay=). The nightly archive plus provider snapshots
383 are the recovery path; for tighter RPO, add continuous replication 403 are the recovery path; for tighter RPO, add continuous replication