Something went wrong. Try again.
Self-hosted Tangled spindle
Something went wrong. Try again.
Files
- Nix 45%
- Shell 40%
- Docker 15%
README.md
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.