spindle-docker#
Early development / personal project — This stack was built for personal use and has not been tested across a wide range of environments. It may have rough edges or undocumented assumptions. Use it at your own risk.
Docker Compose stack for self-hosting a Tangled spindle (CI runner) with OpenBao 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
Configuration#
Docker Compose loads .env automatically. Copy the sample and fill in the two required values:
cp .env.sample .env
| Variable | Required | Default | Description |
|---|---|---|---|
SPINDLE_SERVER_HOSTNAME |
yes | — | Public hostname or IP (e.g. spindle.example.com) |
SPINDLE_SERVER_OWNER |
yes | — | Your ATProto DID (e.g. did:plc:xxxx) |
SPINDLE_PORT |
no | 6555 |
Host port Spindle is exposed on |
OPENBAO_PORT |
no | 8200 |
Host port OpenBao is exposed on (local CLI access) |
SPINDLE_SERVER_LISTEN_ADDR |
no | 0.0.0.0:6555 |
Bind address inside the container |
SPINDLE_SERVER_DB_PATH |
no | /data/spindle.db |
SQLite database path inside the container |
SPINDLE_PIPELINES_LOG_DIR |
no | /var/log/spindle |
Pipeline log directory inside the container |
SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT |
no | spindle |
KV v2 mount name |
First-time setup#
1. Configure environment
cp .env.sample .env
# Edit .env — set SPINDLE_SERVER_HOSTNAME and SPINDLE_SERVER_OWNER
2. Start OpenBao
docker compose up -d openbao
Wait ~5 seconds for it to be healthy.
3. Initialize the vault (once only)
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
docker compose up -d
After a restart#
OpenBao seals itself on every restart. Unseal it before the proxy and spindle can start:
docker compose exec openbao bao operator unseal <unseal_key>
Verify#
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.