Skip to content
Self-hosting

Backup and scaling

Choose the right data layout for one node or many, and make sure the review state can be restored.

Default: SQLite single node

SQLite is the default because it is operationally simple and good enough for a single maintainer instance. The tradeoff is obvious: if the volume is lost, review state is lost.

Do not treat the default data volume as a backup. Snapshot it or enable continuous backup.

Continuous backup with Litestream

.env
BACKUP_ACKNOWLEDGED=true
LITESTREAM_ACCESS_KEY_ID=<key>
LITESTREAM_SECRET_ACCESS_KEY=<secret>
LITESTREAM_ENDPOINT=s3.example.com
LITESTREAM_REGION=us-east-1
docker compose --profile litestream up -d
bash

Multi-instance: Postgres and Redis

Postgres
Use DATABASE_URL for a shared database and queue claiming with SKIP LOCKED semantics.
Redis
Use REDIS_URL for distributed rate limiting, webhook deduplication, and shared short-lived caches.
PgBouncer
Use the pgbouncer profile when many replicas need pooled database connections.
.env
DATABASE_URL=postgres://gittensory:<password>@postgres:5432/gittensory
REDIS_URL=redis://redis:6379
PGVECTOR_ENABLED=true

Restore checks

  • Restore to a separate host or volume, never over the live instance first.
  • Boot the app and confirm /ready returns 200.
  • Confirm migrations do not fail or reapply incorrectly.
  • Confirm recent review rows and job state are present.

After scaling, revisit Operations and Security because network and credential boundaries change.