···11-# ── Required ──────────────────────────────────────────────────────────────────
11+# Copy this file to .env and fill in the required values.
22+# Docker Compose loads .env automatically — no extra flags needed.
2333-# Public hostname of this spindle (e.g. spindle.example.com or an IP)
44+# ── Required ───────────────────────────────────────────────────────────────────
55+66+# Public hostname of this spindle (e.g. spindle.example.com or 192.0.2.1)
47SPINDLE_SERVER_HOSTNAME=
5866-# ATProto DID of the spindle owner (e.g. did:plc:xxxxxxxxxxxxxxxxxxxx)
77-# Find yours at: https://bsky.app → Settings → Privacy and Security → Advanced
88-SPINDLE_SERVER_OWNER=99+# ATProto DID of the spindle owner
1010+# Find yours: https://bsky.app → Settings → Privacy and Security → Advanced
1111+SPINDLE_SERVER_OWNER=
1212+1313+# ── Ports (host-side bindings) ─────────────────────────────────────────────────
1414+1515+# Port Spindle listens on (host)
1616+SPINDLE_PORT=6555
1717+1818+# Port OpenBao server is exposed on (host) — remove the openbao ports: mapping in
1919+# docker-compose.yml if you don't need local CLI/API access
2020+OPENBAO_PORT=8200
2121+2222+# ── Advanced (safe to leave as-is) ────────────────────────────────────────────
2323+2424+# Address Spindle binds inside the container
2525+SPINDLE_SERVER_LISTEN_ADDR=0.0.0.0:6555
2626+2727+# Path to the Spindle SQLite database inside the container
2828+SPINDLE_SERVER_DB_PATH=/data/spindle.db
2929+3030+# Directory for pipeline logs inside the container
3131+SPINDLE_PIPELINES_LOG_DIR=/var/log/spindle
3232+3333+# Secrets backend — only "openbao" is supported
3434+SPINDLE_SERVER_SECRETS_PROVIDER=openbao
3535+3636+# Internal address of the OpenBao proxy sidecar (do not change unless you rename the service)
3737+SPINDLE_SERVER_SECRETS_OPENBAO_PROXY_ADDR=http://openbao-proxy:8201
3838+3939+# KV v2 mount name created by init-openbao.sh
4040+SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT=spindle
+25-6
README.md
···11# spindle-docker
2233+> **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.
44+35Docker Compose stack for self-hosting a [Tangled](https://tangled.org) spindle (CI runner) with [OpenBao](https://openbao.org) for secrets management.
4657```
···17191820- Docker + Docker Compose
1921- A domain or IP reachable by the Tangled network
2020-- Your ATProto DID (find it in Bluesky → Settings → Advanced)
2222+- Your ATProto DID
2323+2424+## Configuration
2525+2626+Docker Compose loads `.env` automatically. Copy the sample and fill in the two required values:
2727+2828+```bash
2929+cp .env.sample .env
3030+```
3131+3232+| Variable | Required | Default | Description |
3333+|----------|----------|---------|-------------|
3434+| `SPINDLE_SERVER_HOSTNAME` | yes | — | Public hostname or IP (e.g. `spindle.example.com`) |
3535+| `SPINDLE_SERVER_OWNER` | yes | — | Your ATProto DID (e.g. `did:plc:xxxx`) |
3636+| `SPINDLE_PORT` | no | `6555` | Host port Spindle is exposed on |
3737+| `OPENBAO_PORT` | no | `8200` | Host port OpenBao is exposed on (local CLI access) |
3838+| `SPINDLE_SERVER_LISTEN_ADDR` | no | `0.0.0.0:6555` | Bind address inside the container |
3939+| `SPINDLE_SERVER_DB_PATH` | no | `/data/spindle.db` | SQLite database path inside the container |
4040+| `SPINDLE_PIPELINES_LOG_DIR` | no | `/var/log/spindle` | Pipeline log directory inside the container |
4141+| `SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT` | no | `spindle` | KV v2 mount name |
21422243## First-time setup
23442445**1. Configure environment**
25462626-Edit `docker-compose.yml` and set these two values under the `spindle` service:
2727-2828-```yaml
2929-SPINDLE_SERVER_HOSTNAME: "spindle.example.com" # your public hostname
3030-SPINDLE_SERVER_OWNER: "did:plc:xxxx" # your ATProto DID
4747+```bash
4848+cp .env.sample .env
4949+# Edit .env — set SPINDLE_SERVER_HOSTNAME and SPINDLE_SERVER_OWNER
3150```
32513352**2. Start OpenBao**
+10-10
docker-compose.yml
···1414 - ./config/openbao/server.hcl:/openbao/config/server.hcl:ro
1515 - openbao-data:/openbao/data
1616 ports:
1717- - "8200:8200" # remove if you don't need local CLI access
1717+ - "${OPENBAO_PORT:-8200}:8200" # remove if you don't need local CLI access
1818 networks:
1919 - spindle-net
2020 healthcheck:
···5656 openbao-proxy:
5757 condition: service_healthy
5858 environment:
5959- SPINDLE_SERVER_HOSTNAME: "" # set to your public hostname
6060- SPINDLE_SERVER_OWNER: "" # set to your ATProto DID
6161- SPINDLE_SERVER_LISTEN_ADDR: "0.0.0.0:6555"
6262- SPINDLE_SERVER_DB_PATH: "/data/spindle.db"
6363- SPINDLE_SERVER_SECRETS_PROVIDER: "openbao"
6464- SPINDLE_SERVER_SECRETS_OPENBAO_PROXY_ADDR: "http://openbao-proxy:8201"
6565- SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT: "spindle"
6666- SPINDLE_PIPELINES_LOG_DIR: "/var/log/spindle"
5959+ SPINDLE_SERVER_HOSTNAME: "${SPINDLE_SERVER_HOSTNAME}"
6060+ SPINDLE_SERVER_OWNER: "${SPINDLE_SERVER_OWNER}"
6161+ SPINDLE_SERVER_LISTEN_ADDR: "${SPINDLE_SERVER_LISTEN_ADDR:-0.0.0.0:6555}"
6262+ SPINDLE_SERVER_DB_PATH: "${SPINDLE_SERVER_DB_PATH:-/data/spindle.db}"
6363+ SPINDLE_SERVER_SECRETS_PROVIDER: "${SPINDLE_SERVER_SECRETS_PROVIDER:-openbao}"
6464+ SPINDLE_SERVER_SECRETS_OPENBAO_PROXY_ADDR: "${SPINDLE_SERVER_SECRETS_OPENBAO_PROXY_ADDR:-http://openbao-proxy:8201}"
6565+ SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT: "${SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT:-spindle}"
6666+ SPINDLE_PIPELINES_LOG_DIR: "${SPINDLE_PIPELINES_LOG_DIR:-/var/log/spindle}"
6767 volumes:
6868 - /var/run/docker.sock:/var/run/docker.sock # spindle spawns pipeline containers on the host daemon
6969 - spindle-db:/data
7070 - spindle-logs:/var/log/spindle
7171 ports:
7272- - "6555:6555"
7272+ - "${SPINDLE_PORT:-6555}:6555"
7373 networks:
7474 - spindle-net
7575