Self-hosting
A spindle is Tangled’s CI runner. It watches the knots of the
repositories it serves, runs their .tangled/workflows/*.yml in
microVMs or containers, and serves status and logs over XRPC. Run a
spindle is the short version of this page.
Signing key
Section titled “Signing key”The spindle signs with an EC P-256 key that it publishes in its DID
document. It never generates one, so make it once and point
SPINDLE_SERVER_KEY_PATH (NixOS: keyPath) at it:
openssl ecparam -name prime256v1 -genkey -noout -out /var/lib/secrets/spindle-key.pemRequirements
Section titled “Requirements”- Linux with KVM for the
microvmengine, or Docker for thenixeryengine. - A recent
git. - A public hostname with TLS.
Install on NixOS
Section titled “Install on NixOS”Import nixosModules.spindle from the Tangled flake:
{ imports = [ tangled.nixosModules.spindle ];
services.tangled.spindle = { enable = true; server = { hostname = "spindle.example.com"; owner = "did:plc:yourdid"; }; keyPath = "/var/lib/secrets/spindle-key.pem"; contact.email = "admin@spindle.example.com"; artifactStores.s3.bucket = ""; };
systemd.tmpfiles.rules = [ "L+ /var/lib/spindle/images/nixos - - - - ${tangled.packages.x86_64-linux.spindle-nixos-image}" ];}The module enables the vhost, vsock and vhost_vsock kernel
modules and puts qemu, e2fsprogs, slirp4netns, iproute2 and
util-linux on the service’s PATH.
Put it behind an HTTPS reverse proxy to port 6555 that passes websocket
upgrades and sends CORS headers. State lives in /var/lib/spindle, and
secrets such as AWS credentials go in environmentFile.
Run a spindle walks through a first
install.
Elsewhere. Build with nix build .#spindle, set the environment,
and run spindle. There is no container image.
MicroVM images
Section titled “MicroVM images”Workflows pick an image by name, for example image: nixos. Spindle
looks for it in SPINDLE_MICROVM_PIPELINES_IMAGE_DIR. The flake builds
spindle-nixos-image, spindle-alpine-image and
spindle-almalinux10-image.
Admins, admission and repositories
Section titled “Admins, admission and repositories”Admins are the owner plus SPINDLE_SERVER_ADMINS. With
SPINDLE_SERVER_ADMISSION=closed (the default) the spindle serves only
admins and its allow-list; with open it serves anyone who isn’t
banned.
spindle allowlist add friend.example.comspindle inviteA repository is served when its manifest names this spindle and its owner is admitted.
Secrets
Section titled “Secrets”Repository secrets live in spindle.db (the default) or in OpenBao
(SPINDLE_SERVER_SECRETS_PROVIDER=openbao). They are masked in logs and
withheld from fork runs.
Logs and artifacts
Section titled “Logs and artifacts”Logs are written to SPINDLE_SERVER_LOG_DIR, then archived to a disk
directory or an S3 bucket. The NixOS module defaults to the
tangled-logs bucket; set artifactStores.s3.bucket = "" to keep logs
on disk.
CI logs over SSH
Section titled “CI logs over SSH”Run a cilogs server (nixosModules.cilogs) and set
SPINDLE_SERVER_LOGS_ADDR to its host:port. Pushes then print an
ssh command that follows the run.
Caches
Section titled “Caches”- Nix binary cache: microVM guests read from
SPINDLE_NIX_CACHE_READ_URLSand upload toSPINDLE_NIX_CACHE_UPLOAD_URL. - CI cache: backs the workflow
cachefield. SetSPINDLE_CACHE_BACKENDtodiskors3.
Quotas
Section titled “Quotas”SPINDLE_QUOTA_USER_* and SPINDLE_QUOTA_REPO_* cap workflows, CPU,
memory, disk, cache and CI minutes. Override them per user:
spindle quota set friend.example.com --resource workflows --limit 4spindle quota usagespindle ban did:plc:spammerOIDC tokens for workflows
Section titled “OIDC tokens for workflows”Set SPINDLE_OIDC_ISSUER and SPINDLE_OIDC_KEY_PATH (an EC P-256 key)
to give trusted workflows an OIDC token for their audience:.
Mill and executors
Section titled “Mill and executors”A spindle can split into a mill, which places jobs, and
executors, which run them. Set SPINDLE_ROLE to mill or
executor, and register each executor on the mill:
spindle mill executor token generate --db /var/lib/spindle/spindle.db > exec-a.tokenspindle mill executor add --db /var/lib/spindle/spindle.db --token-file exec-a.token --label kvm exec-aThe mill and executors must share one artifact store.
Troubleshooting
Section titled “Troubleshooting”- Pushes never trigger anything: check that the owner is admitted and not banned.
- A workflow fails with a missing tool or device: install what the error names, see Requirements.
- Runs are slow to start: check
SPINDLE_SERVER_MAX_JOB_COUNTandspindle quota usage.
Spindle Configuration lists every setting.