# spindle-docker Docker Compose stack for self-hosting a [Tangled](https://tangled.org) spindle (CI runner) with [OpenBao](https://openbao.org) for secrets management. ``` . ├── docker-compose.yml ├── Dockerfile ├── init-openbao.sh # one-time vault bootstrap └── config/openbao/ ├── server.hcl # OpenBao server config ├── proxy.hcl # AppRole auto-auth proxy config └── spindle-policy.hcl # KV access policy for spindle ``` ## Prerequisites - Docker + Docker Compose - A domain or IP reachable by the Tangled network - Your ATProto DID (find it in Bluesky → Settings → Advanced) ## First-time setup **1. Configure environment** Edit `docker-compose.yml` and set these two values under the `spindle` service: ```yaml SPINDLE_SERVER_HOSTNAME: "spindle.example.com" # your public hostname SPINDLE_SERVER_OWNER: "did:plc:xxxx" # your ATProto DID ``` **2. Start OpenBao** ```bash docker compose up -d openbao ``` Wait ~5 seconds for it to be healthy. **3. Initialize the vault** (once only) ```bash chmod +x init-openbao.sh ./init-openbao.sh ``` Save the **unseal key** and **root token** printed to stdout — they are not stored anywhere. **4. Start the full stack** ```bash docker compose up -d ``` ## After a restart OpenBao seals itself on every restart. Unseal it before the proxy and spindle can start: ```bash docker compose exec openbao bao operator unseal ``` ## Verify ```bash curl http://localhost:8201/v1/sys/health # OpenBao proxy curl http://localhost:6555/ # Spindle ``` ## Architecture ``` spindle (:6555) → openbao-proxy (:8201) → openbao (:8200) spindle → /var/run/docker.sock (pipeline containers run on the host daemon) ``` - **openbao** — secrets vault; sealed on every start - **openbao-proxy** — AppRole sidecar; auto-authenticates and exposes a token-authenticated proxy to spindle - **spindle** — the CI runner; starts only after the proxy is healthy ## Notes - Port 8200 is exposed for local CLI access. Remove that port mapping in production. - TLS is disabled on both listeners. Put nginx or Caddy in front for production traffic. - Spindle mounts the Docker socket, so pipeline containers run on the **host** daemon.