···11+# tangled spindle + openbao
22+33+## Layout
44+55+```
66+.
77+├── docker-compose.yml
88+├── Dockerfile.spindle # clones & builds from tangled.org/core
99+├── .env.example # copy to .env and fill in
1010+├── config/
1111+│ └── openbao/
1212+│ ├── server.hcl # production file-backend config
1313+│ ├── proxy.hcl # AppRole auto-auth proxy
1414+│ └── spindle-policy.hcl # KV policy for spindle
1515+└── scripts/
1616+ └── init-openbao.sh # one-time vault bootstrap
1717+```
1818+1919+## First-time setup
2020+2121+### 1. Configure spindle
2222+2323+```bash
2424+cp .env.example .env
2525+# edit .env — set SPINDLE_SERVER_HOSTNAME and SPINDLE_SERVER_OWNER
2626+```
2727+2828+### 2. Start OpenBao only
2929+3030+```bash
3131+docker compose up -d openbao
3232+```
3333+3434+Wait for it to be healthy (~5 s), then:
3535+3636+### 3. Initialise the vault
3737+3838+```bash
3939+chmod +x scripts/init-openbao.sh
4040+./scripts/init-openbao.sh
4141+```
4242+4343+Save the unseal key and root token printed to stdout.
4444+4545+### 4. Start the rest of the stack
4646+4747+```bash
4848+docker compose up -d
4949+```
5050+5151+Spindle comes up only after the proxy is healthy, which is after the vault
5252+is unsealed and AppRole credentials are in the shared volume.
5353+5454+## After a restart
5555+5656+OpenBao is **sealed on every restart** — that's intentional for production.
5757+Unseal it before the proxy (and therefore spindle) can authenticate:
5858+5959+```bash
6060+docker compose exec openbao bao operator unseal http://localhost:8200 <unseal_key>
6161+```
6262+6363+Or automate this with a secrets manager / HSM if you don't want manual steps.
6464+6565+## Verify
6666+6767+```bash
6868+# proxy health
6969+curl http://localhost:8201/v1/sys/health
7070+7171+# spindle port
7272+curl http://localhost:6555/
7373+```
7474+7575+## Notes
7676+7777+- Spindle mounts `/var/run/docker.sock` so it can spawn pipeline containers
7878+ on the **host** Docker daemon — make sure the spindle user has permission.
7979+- TLS is disabled on both listeners; put a reverse proxy (nginx/caddy) in
8080+ front for production traffic.
8181+- The `openbao-approle` volume holds the role-id/secret-id written by the
8282+ init script and mounted read-only by the proxy container.