tangled spindle + openbao#
Layout#
.
├── docker-compose.yml
├── Dockerfile.spindle # clones & builds from tangled.org/core
├── .env.example # copy to .env and fill in
├── config/
│ └── openbao/
│ ├── server.hcl # production file-backend config
│ ├── proxy.hcl # AppRole auto-auth proxy
│ └── spindle-policy.hcl # KV policy for spindle
└── scripts/
└── init-openbao.sh # one-time vault bootstrap
First-time setup#
1. Configure spindle#
cp .env.example .env
# edit .env — set SPINDLE_SERVER_HOSTNAME and SPINDLE_SERVER_OWNER
2. Start OpenBao only#
docker compose up -d openbao
Wait for it to be healthy (~5 s), then:
3. Initialise the vault#
chmod +x scripts/init-openbao.sh
./scripts/init-openbao.sh
Save the unseal key and root token printed to stdout.
4. Start the rest of the stack#
docker compose up -d
Spindle comes up only after the proxy is healthy, which is after the vault is unsealed and AppRole credentials are in the shared volume.
After a restart#
OpenBao is sealed on every restart — that's intentional for production. Unseal it before the proxy (and therefore spindle) can authenticate:
docker compose exec openbao bao operator unseal http://localhost:8200 <unseal_key>
Or automate this with a secrets manager / HSM if you don't want manual steps.
Verify#
# proxy health
curl http://localhost:8201/v1/sys/health
# spindle port
curl http://localhost:6555/
Notes#
- Spindle mounts
/var/run/docker.sockso it can spawn pipeline containers on the host Docker daemon — make sure the spindle user has permission. - TLS is disabled on both listeners; put a reverse proxy (nginx/caddy) in front for production traffic.
- The
openbao-approlevolume holds the role-id/secret-id written by the init script and mounted read-only by the proxy container.