Orbit documentation

Backups and migrations

Data layout

  • Postgres
    • public schema: platform data (tenant registry, accounts, memberships, licenses, superadmins, sessions).
    • One schema per tenant: tenant_<identifier>, holding all of that organisation's data. Each request runs with search_path set to the tenant's schema.
  • S3 bucket (S3_BUCKET): uploaded files, under tenant/<tenantId>/documents/<documentId>/versions/<versionId><ext>, each tagged with the tenant ID.

Back up both. Documents in the database refer to objects in the bucket.

Backups

# Database (all schemas)
docker compose exec -T postgres pg_dump -U orbit -Fc orbit > orbit-$(date +%F).dump

# Files (any S3 client), for example:
aws --endpoint-url http://localhost:8334 s3 sync s3://orbit-storage ./orbit-files-$(date +%F)

Restore:

docker compose exec -T postgres pg_restore -U orbit -d orbit --clean < orbit-YYYY-MM-DD.dump
aws --endpoint-url http://localhost:8334 s3 sync ./orbit-files-YYYY-MM-DD s3://orbit-storage

One tenant only: pg_dump -n tenant_<identifier>. You also need its rows in public (registry, memberships) to restore it on another platform.

Test restores regularly on a non-production stack.

Migrations

pnpm migrate          # public + every tenant schema
  • The API and worker also migrate at start-up, so a deploy migrates automatically.
  • Each schema records the migrations it has applied in its own _orbitMigrations table, so new tenants and old ones converge.
  • System definition sets are ensured in every tenant on each migration.
  • Developers generate migrations with pnpm db:generate after changing packages/db/src/schema.

Upgrading

  1. Back up the database and bucket.
  2. Pull the new version, then docker compose up -d --build.
  3. Watch the API log for migration output; check /v1/status and sign in.