Self-hosted Tangled spindle
spindle README.md
2.1 kB · 45 lines
Markdown
at main

spindle #

Our own Tangled spindle: the CI runner for the repos under demi.dev, starting with demi.dev/pneumo.

We run it because Tangled's hosted spindle denies every nixery workflow: the engine requests 6 GiB per job, and the hosted per-repo quota is 4 GiB. The decision and the rejected options are in ADR 0001.

Architecture #

knot (tangled.org) ──events──▶ mill (Railway, spindle.demi.dev)
                                  ▲  wss://spindle.demi.dev/mill
                                  │  (the executor dials out)
                     executor (NixOS VM on the home server, nixery on Docker)

mill and executor share one Railway bucket as the artifact store
Piece Where State
Mill (SPINDLE_ROLE=mill) Railway project spindle, built from mill/Dockerfile Volume /data (SQLite, repos, logs). Identity did:web:spindle.demi.dev, from the signing key in the Railway variable SPINDLE_SIGNING_KEY_PEM
Executor (SPINDLE_ROLE=executor) VM spindle-exec-1 on the owner's home server, built from executor/flake.nix Executor token and bucket credentials in /var/lib/secrets/ on the VM
Artifact store Railway bucket in project spindle Workflow artifacts and logs

Tangled v1.20.0 (2096d06d) is pinned in mill/Dockerfile and executor/flake.nix; they are always bumped together.

Layout #

Path What
mill/ The mill's container image
executor/ The executor VM's NixOS configuration
executor/bootstrap/ The minimal NixOS image the VM was first created from
docs/adr/ Decisions
docs/runbook.md Operating the spindle: upgrades, token rotation, backups and outages

Checks #

Needs mise and a running Docker. Nix runs in a pinned nixos/nix container, so you don't need it on the host.

mise install
mise run check

Agents: read CLAUDE.md first.