On-prem deploy

Install TheSpider on-prem with Docker Compose or Helm

On-prem, you bring your own Postgres, object storage, and model credentials — we never store your data. The server image migrates on boot and serves the API, auth, and web SPA from one origin.

Quickstart (Docker Compose)

deploy/
cp deploy/.env.example deploy/.env
# Edit deploy/.env — at minimum set:
#   BETTER_AUTH_SECRET   (openssl rand -base64 48)
#   LICENSE_JWT          (from your vendor; without it the instance is read-only)
docker compose -f deploy/docker-compose.yml up -d --build

Then verify:

curl -fsS http://localhost:8080/healthz     # {"status":"ok","mode":"onprem",...}
open http://localhost:8080/                  # the web UI (same origin as the API)

up builds the image (context = repo root), starts Postgres 16 + the server, and the server migrates-on-boot then serves. Add --profile s3 to also start a bundled MinIO.

Bring your own Postgres

Point DATABASE_URL at your own database and drop the bundled service:

DATABASE_URL=postgres://user:pass@db.internal:5432/thespider \
  docker compose -f deploy/docker-compose.yml up -d server   # start only the server

The server needs a role that can create tables and (for RLS) SET ROLE app_role — a normal owner role of the target database is sufficient; migrate-on-boot creates app_role itself.

Bring your own object storage

Slice artifacts (rendered prompt / raw stdout / stderr) are content-addressed by sha256 provenance blobs — the parsed content already lives in reports. Default is the on-disk ARTIFACTS_DIR volume. For S3/MinIO/R2, set S3_BUCKET (+ endpoint/creds):

deploy/
# bundled MinIO:
docker compose -f deploy/docker-compose.yml --profile s3 up -d --build
# then in .env: S3_BUCKET=thespider  S3_ENDPOINT=http://minio:9000
#               S3_ACCESS_KEY_ID=thespider  S3_SECRET_ACCESS_KEY=thespider123
# create the bucket once (mc mb) — the server does not auto-create it.

See Data handling for the 90-day artifact lifecycle recipe.

Enroll a client

Mint a single-use enrollment code inside the container, then drive the Rust agent:

docker compose -f deploy/docker-compose.yml exec server \
  bun run src/mint-enrollment-code.ts --org default --project default
# copy the printed `code:` value, then on a machine with model CLIs + a checkout:
echo "<code>" | thespider-agent login          # server = http://<host>:8080 in config.toml
thespider-agent run                             # claim → run models locally → submit findings
thespider-agent gate --campaign <id>            # CI-style pass/fail

The default project is campaign-ready at first boot — the image bundles a default methodology snapshot seeded as config_version 1, with the sonnet model enabled. Author your real buckets/passes/categories in the web UI (each save becomes a new immutable config_version).

Deploy on Kubernetes (Helm)

A minimal chart lives at deploy/helm/thespider (BYO Postgres — the chart deploys none):

helm install ts deploy/helm/thespider \
  --set secrets.betterAuthSecret="$(openssl rand -base64 48)" \
  --set secrets.licenseJwt="<jwt>" \
  --set config.databaseUrl="postgres://user:pass@postgres:5432/thespider" \
  --set image.repository=<your-registry>/thespider-server --set image.tag=<version>
# expose it:
helm upgrade ts deploy/helm/thespider --reuse-values \
  --set ingress.enabled=true --set ingress.host=thespider.example.com

The chart renders a Deployment, Service, optional Ingress, a Secret (license/auth/S3/AI keys), and a PVC for the on-disk artifact store. helm lint + helm template validate it.

Back up

The Postgres database is the source of truth — it holds every finding, triage decision, config version, and usage event. Back it up on a schedule:

docker compose -f deploy/docker-compose.yml exec -T postgres \
  pg_dump -U postgres thespider | gzip > thespider-$(date +%F).sql.gz

Artifacts (the thespider_artifacts volume / S3 bucket) are regenerable provenance — back them up only if you need the raw prompt/output blobs. The thespider_pg volume is the one that matters.

Upgrade

Pull/rebuild the new image and restart; migrate-on-boot applies additive migrations automatically:

docker compose -f deploy/docker-compose.yml up -d --build

To refresh methodology, pull an update bundle from the vendor (GET /v1/method-updates, license-JWT-authenticated) and apply it as a new immutable config version:

docker compose -f deploy/docker-compose.yml exec server \
  bun run src/apply-methodology.ts --project default --file /path/to/snapshot.json

Verify the install

bash deploy/verify-onprem.sh

See deploy/air-gap.md for the fully-offline story.

Next steps