SporeDB Self-Hosted Deployment Guide¶
Deploy SporeDB on your own infrastructure with full FDA 21 CFR Part 11
and EU Annex 11 compliance. The self-hosted deployment uses the same
Docker image as the cloud tier with SPOREDB_MODE=selfhosted.
Prerequisites¶
| Requirement | Minimum |
|---|---|
| Docker Engine | >= 24.0 |
| Docker Compose | >= 2.20 |
| CPU | 4 cores |
| RAM | 8 GB |
| Disk | 100 GB SSD |
| OS | Linux (kernel >= 5.10) or macOS 13+ |
One-Liner Quick Start¶
Get SporeDB running in a single command:
git clone https://github.com/spore-db/SporeDB.git && cd SporeDB && make generate-keys && make build && make up
This clones the repo, generates Ed25519 keys, builds the Docker image, and starts
all services (SporeDB, PostgreSQL, MinIO). SporeDB will be available at
http://localhost:8000.
For a step-by-step setup, see the full Quick Start below.
Quick Start¶
# 1. Clone the repository
git clone https://github.com/spore-db/SporeDB.git
cd SporeDB
# 2. Generate Ed25519 signing keys, build images, and start all services
make generate-keys && make build && make up
# 3. Verify all services are healthy
make status
# 4. Confirm compliance checks pass
make validate-compliance
SporeDB is now running at http://localhost:8000. The OpenAPI docs
are available at http://localhost:8000/docs.
Configuration¶
All settings are in a single sporedb.yml file. Environment
variables with the SPOREDB_ prefix override any YAML value.
Server¶
server:
host: 0.0.0.0 # Bind address
port: 8000 # HTTP port
workers: 4 # Uvicorn worker count (set to CPU count)
Database¶
Change changeme to a strong password. Set the same password in the
POSTGRES_PASSWORD environment variable for the Postgres container.
Object Storage¶
storage:
type: s3
endpoint: http://minio:9000
access_key: minioadmin
secret_key: minioadmin
bucket: sporedb
region: us-east-1
For production, change the MinIO credentials and configure TLS.
Authentication¶
auth:
jwt_private_key_path: keys/cloud_private.pem
jwt_public_key_path: keys/cloud_public.pem
jwt_algorithm: EdDSA
access_token_expire_minutes: 15
refresh_token_expire_days: 7
Keys are generated by make generate-keys. Back up the private key
securely -- losing it invalidates all issued tokens.
Compliance¶
compliance:
audit_trail: true # Enable tamper-evident audit log
require_signatures: true # Ed25519 sign all audit entries
rbac_enabled: true # Enforce role-based access control
All three settings are true by default in self-hosted mode. Do not
disable them if you need 21 CFR Part 11 compliance.
CORS¶
Environment Variables Reference¶
All configuration can be set via environment variables with the SPOREDB_ prefix.
These override values in sporedb.yml.
Warning: Change all default credentials (
minioadmin,changeme) before deploying to production. The defaults are for local development only.
| Variable | Default | Description |
|---|---|---|
SPOREDB_MODE |
selfhosted |
Deployment mode (selfhosted or cloud) |
SPOREDB_SERVER_HOST |
0.0.0.0 |
HTTP bind address |
SPOREDB_SERVER_PORT |
8000 |
HTTP port |
SPOREDB_SERVER_WORKERS |
4 |
Uvicorn worker count |
SPOREDB_DATABASE_URL |
(required) | PostgreSQL connection string (postgresql+asyncpg://user:pass@host:5432/db) |
SPOREDB_S3_ENDPOINT |
http://minio:9000 |
S3-compatible endpoint URL |
SPOREDB_S3_ACCESS_KEY |
minioadmin |
Object storage access key |
SPOREDB_S3_SECRET_KEY |
minioadmin |
Object storage secret key |
SPOREDB_S3_BUCKET |
sporedb |
Storage bucket name |
SPOREDB_S3_REGION |
us-east-1 |
Storage region |
SPOREDB_JWT_SECRET_KEY_PATH |
keys/cloud_private.pem |
Ed25519 private key path |
SPOREDB_JWT_PUBLIC_KEY_PATH |
keys/cloud_public.pem |
Ed25519 public key path |
SPOREDB_JWT_ALGORITHM |
EdDSA |
JWT signing algorithm |
SPOREDB_JWT_ACCESS_TOKEN_EXPIRE_MINUTES |
15 |
Access token TTL |
SPOREDB_JWT_REFRESH_TOKEN_EXPIRE_DAYS |
7 |
Refresh token TTL |
SPOREDB_COMPLIANCE_AUDIT_TRAIL |
true |
Enable tamper-evident audit log |
SPOREDB_COMPLIANCE_REQUIRE_SIGNATURES |
true |
Ed25519 sign all audit entries |
SPOREDB_COMPLIANCE_RBAC_ENABLED |
true |
Enforce role-based access control |
POSTGRES_PASSWORD |
changeme |
PostgreSQL container password |
Verifying Compliance¶
Run the built-in compliance validator to confirm that the self-hosted deployment has the same compliance guarantees as the cloud tier:
This executes sporedb.compliance.validator --check inside the
SporeDB container, which verifies:
- SHA-256 hash chain integrity of the audit trail
- Ed25519 signature validity on all audit entries
- Merkle tree consistency
- Required field completeness
- Audit entry format (UUID, UTC timestamps, user attribution)
- RBAC access control enforcement
Exit code 0 means all checks pass.
Upgrading¶
# Pull the latest code
git pull origin main
# Rebuild and restart
make down && make build && make up
# Verify after upgrade
make validate-compliance
Backup¶
PostgreSQL (metadata)¶
MinIO (Parquet data files)¶
Install the MinIO client (mc) and mirror the bucket:
mc alias set sporedb-local http://localhost:9000 minioadmin minioadmin
mc mirror sporedb-local/sporedb ./backup/minio/
Restore¶
# PostgreSQL
cat backup_20260428.sql | docker compose exec -T postgres psql -U sporedb sporedb
# MinIO
mc mirror ./backup/minio/ sporedb-local/sporedb
Troubleshooting¶
Services not starting¶
Check logs:
Health check failing¶
Verify the SporeDB container can reach Postgres and MinIO:
docker compose exec sporedb curl -f http://localhost:8000/health
docker compose exec sporedb python -c "import asyncpg; print('asyncpg OK')"
Key pair issues¶
Regenerate keys (invalidates existing tokens):