rabun-git architecture
How the forge is put together (layout, ACL, systemd).
How the forge is put together (layout, ACL, systemd). For a beginner walkthrough with examples, start at the user guide.
Self-hosted git forge CLI. Burton and Rabun do not import this crate. Warehouse workers remain the writers of warehouse trees; this process is a git remote they may push to.
This machine Your server
git clone/push --SSH:2222--> rabun-git serve (russh)
ssh git@host request … ----> same binary, management commands
bare repos under RABUN_GIT_ROOT/repos/
users.yaml, keys/, access.yaml
refs/rabun/requests/*
.rabun/workflows runner
SSH is the only public network surface (default 0.0.0.0:2222; russh username git). Loopback GET /health is companion heartbeat only (127.0.0.1:8792). There is no HTTP git UI. The systemd user is rabun-git; admin SSH on port 22 is unchanged.
Layout
$RABUN_GIT_ROOT/ (default data/git):
users.yaml— login + forge admin flagkeys/<user>.pub— OpenSSH public keysaccess.yaml—owner/name→ user →read|write|adminrepos/<owner>/<name>.git/— bare repositoriesruns/<owner>/<name>/<run-id>/—status.yaml+log.txtssh_host_ed25519_key— generated on firstservestatus.json—rabun.companion/v1
ACL
- Forge admin (
users.yaml) bypasses per-repo ACL. - Local CLI (
rabun-giton the host) is the operator and has full access. - SSH identity is the key. Username
gitmaps to the key's owner (GitHub-style). read: fetch, list requests/runs.write: push non-protected branches, open/review requests.admin(repo or forge): pushmaster/main, merge, grant access.hooks/updaterejects protected-branch updates for non-admins. Env:RABUN_GIT_USER,RABUN_GIT_REPO,RABUN_GIT_ROOT,RABUN_GIT_BIN.
Merge requests
Stored in git so they clone with the repo:
refs/rabun/requests/<id>/headrefs/rabun/requests/<id>/baserefs/rabun/requests/<id>/meta— YAML blob (title, author, state, reviews)
git push origin HEAD:refs/rabun/requests/new/<branch> allocates the next id after receive-pack. Merge is fast-forward only in v1.
Workflows
.rabun/workflows/*.yml at the triggering commit. Subset: on.push.branches, on.tag, on.request, jobs.*.steps[].run, env, timeout_minutes. No uses:, matrix, or containers. The runner is trusted (same machine, same rabun-git systemd user).
systemd
Pack this checkout and copy it onto Ubuntu over SSH (same flow as Burton and Rabun): deploy Ubuntu. The unit shipped in deploy/ubuntu/rabun-git.service runs as user rabun-git with forge data under /var/lib/rabun-git. Git clients still use ssh://git@HOST:2222/….
[Unit]
Description=Rabun git forge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=rabun-git
Group=rabun-git
WorkingDirectory=/var/lib/rabun-git
Environment=RABUN_GIT_CONFIG=/etc/rabun-git/rabun-git.toml
Environment=RABUN_GIT_ROOT=/var/lib/rabun-git
EnvironmentFile=-/etc/rabun-git/rabun-git.env
ExecStart=/usr/local/bin/rabun-git serve
Restart=on-failure
Optional companion rabun.toml on the host (register-app.sh upserts this on install):
[[apps]]
name = "git"
description = "Rabun git forge"
command = "rabun-git"
args = ["serve"]
health_url = "http://127.0.0.1:8792/health"
status_file = "/var/lib/rabun-git/status.json"
Settings stay in /etc/rabun-git/rabun-git.env, not /etc/rabun/rabun.env.
Privacy
No telemetry and no outbound forge calls. Host keys and user keys stay on disk you own. Companion JSON never includes key material.