Deployment

Docker

Deploying Spectron with Docker and Docker Compose.

Docker Compose is the fastest way to run the full Spectron stack locally. The compose file starts Spectron and SurrealDB together with a single command.

  • Docker Desktop 4.x or later (includes Docker Compose v2)

  • An OpenAI or Anthropic API key for LLM operations

Create a compose.yaml file in a new directory:

services:
surrealdb:
image: surrealdb/surrealdb:latest
working_dir: /data
environment:
SURREAL_PATH: rocksdb://surrealdb
command: start --log info --user root --pass secret
volumes:
- surrealdb-data:/data
ports:
- "8000:8000"
healthcheck:
test: ["CMD", "surreal", "isready", "--endpoint", "http://localhost:8000"]
interval: 5s
timeout: 5s
retries: 10

spectron:
image: ghcr.io/surrealdb/spectron:latest
depends_on:
surrealdb:
condition: service_healthy
env_file:
- .env
environment:
SPECTRON_SURREALDB_URL: ws://surrealdb:8000
SPECTRON_OBJECT_STORE_URL: file:///var/docs/spectron/objects
volumes:
- spectron-objects:/var/docs/spectron/objects
ports:
- "9090:9090"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
interval: 10s
timeout: 5s
retries: 5

volumes:
surrealdb-data:
spectron-objects:

The compose file uses two different path schemes for two different systems:

SettingUsed byPurpose
working_dir: /data + SURREAL_PATH: rocksdb://surrealdbSurrealDBOn-disk database files. working_dir must match the volume mount (/data here). RocksDB creates a surrealdb directory inside that mount — not a single .db file.
file:///var/docs/spectron/objectsSpectron (SPECTRON_OBJECT_STORE_URL)Object store for uploaded document originals. Unrelated to SurrealDB's database path.

Spectron connects to the running SurrealDB server over ws://surrealdb:8000 — a network client URL, not a storage path.

SurrealDB path slashes are easy to mistype. The form rocksdb://… (two slashes) is relative to working_dir. Forms like rocksdb:/… or rocksdb:///… are absolute paths on the container filesystem.

If you see Failed to create RocksDB directory or a read-only filesystem error, you may have accidentally used an absolute path (often by dropping a slash from rocksdb://rocksdb:/…), so SurrealDB tries to write under / instead of your mounted volume.

PathMeaning
rocksdb://surrealdb with working_dir: /dataDatabase at /data/surrealdb (this compose file)
rocksdb:/data/surrealdbAbsolute /data/surrealdb (works if /data is mounted, but easier to typo)
rocksdb:/surrealdbAbsolute /surrealdb at filesystem root — usually fails with permission or read-only errors

Keep working_dir and the volume mount in sync. If you change the mount from /data to something else, update working_dir to match.

See SurrealDB file-backed storage for the full path rules.

Create a .env file alongside compose.yaml. Never commit this file to version control.

# .env
OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-ant-... # uncomment if using Anthropic models
docker compose up -d

Docker pulls the images and starts both services. Wait for the health checks to pass – SurrealDB starts first, then Spectron connects to it.

Check that both services are healthy:

docker compose ps
NAME              STATUS
spectron-1 Up (healthy)
surrealdb-1 Up (healthy)

Before you can use Spectron, create an admin management key. Run this command once against the running container:

docker compose exec spectron spectron init --admin-key

The command prints a management key secret. Copy it immediately – it is not stored in recoverable form. Store it in a secrets manager or a .env file (outside version control).

Admin key created.
Name: admin
Secret: sk_mgmt_...

This secret will not be shown again. Store it securely.

Set the management key in your shell:

export SPECTRON_MGMT_KEY=sk_mgmt_...

A Context is the top-level container for a Spectron deployment. Create one with the management key:

curl -s -X POST http://localhost:9090/api/v1/contexts \
-H "API-KEY: $SPECTRON_MANAGEMENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "dev",
"namespace": "spectron",
"database": "dev",
"config": {
"models": {
"extraction": "openai/gpt-4o-mini",
"response": "openai/gpt-4o"
}
}
}'

Create an agent key for the Context:

curl -s -X POST http://localhost:9090/api/v1/contexts/dev/keys/my-agent \
-H "API-KEY: $SPECTRON_MANAGEMENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"principal": "agent",
"scope_floor": { "org": "my-org", "agent": "my-agent" }
}'

The response includes the key secret. Use it in your application as SPECTRON_API_KEY.

curl http://localhost:9090/health
{
"status": "ok",
"surrealdb": "connected",
"object_store": "ok",
"version": "0.1.0"
}

A 200 OK response with "status": "ok" means Spectron is running and connected to all dependencies.

# All services
docker compose logs -f

# Spectron only
docker compose logs -f spectron
docker compose down

Data persists in the named volumes (surrealdb-data, spectron-objects) and is available when you restart.

Pull the latest image and restart the Spectron service. Migrations run automatically at startup.

docker compose pull spectron
docker compose up -d spectron

SurrealDB should be upgraded separately. Follow SurrealDB's upgrade guide before updating surrealdb/surrealdb in your compose file.

The configuration above is suitable for development and small internal deployments. For production, review the following before going live:

  • Replace file:///var/docs/spectron/objects with an S3 or GCS URL so object storage is not tied to the container's local filesystem.

  • Place Spectron behind a TLS-terminating reverse proxy (Nginx, Caddy, or a cloud load balancer).

  • Store all secrets in a secrets manager rather than a plain .env file.

  • Set SPECTRON_MAX_UPLOAD_BYTES to match your upload policy.

See Kubernetes for a production-grade deployment guide.

Was this page helpful?