Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Operations: health, backups, upgrades

8. Operations

8.1 Health and readiness

curl -fsS http://127.0.0.1:5000/health        # -> ok
curl -fsS -H "Authorization: Bearer $KEY" \
  https://social.example.com/public/v1/providers/status | jq

providers/status returns, per provider:

{
  "identifier": "x",
  "name": "X",
  "configured": true,
  "missing": [],
  "connection": "oauth"
}

Only variable names are reported, never values. A provider with configured:false is refused before an OAuth URL is generated; the error names the missing variables and the redirect URI to register.

8.2 Logs

Logs go to stderr as plain-text tracing lines (the default subscriber format, with fields appended). Useful filters:

RUST_LOG=info,rustiz=debug,sqlx=warn,tower_http=info rustiz serve

Do not send MCP stdio logs to stdout. If you wrap rustiz mcp in a supervisor, route stderr to a file and leave stdout for the protocol.

8.3 Backups

Back up both the database and JWT_SECRET.

# Online, consistent backup (WAL aware).
sqlite3 /var/lib/rustiz/rustiz.db \
  ".backup '/var/backups/rustiz-$(date +%F).db'"

# Or stop the service and copy the database plus any -wal/-shm files.
systemctl stop rustiz
cp -a /var/lib/rustiz/rustiz.db* /var/backups/
systemctl start rustiz

Also back up config.env (or at least JWT_SECRET and RUSTIZ_API_KEY) and the upload directory or bucket. A database restored without the original secret can no longer decrypt customFields credentials or custom-instance client information, so those channels must be reconnected. Provider access tokens remain readable because they are stored in plain text in the database — which also means a database backup is a bearer-credential backup: encrypt it and restrict access to it.

Test restores on a separate copy. Do not run two servers against the same SQLite file over NFS or a network filesystem.

8.4 Upgrades

  1. Back up.
  2. Build/copy the new binary.
  3. rustiz migrate (or just start; migrations run automatically).
  4. Restart serve and worker; graceful shutdown closes MCP subscription streams.
  5. Check /health and providers --status.

Schema migrations are applied in order and are not automatically reversible. Read the release notes before a downgrade.

8.5 Scaling

  • One SQLite file supports one writer at a time. Scale vertically first: WORKER_CONCURRENCY, MCP_SUBSCRIPTIONS_MAX_STREAMS, REQUEST_LIMIT.
  • Multiple serve replicas are possible only with a shared database; SQLite on a shared local volume is not safe across hosts. Object storage is required for media if replicas do not share a volume.
  • Rate limits are per process, so N replicas mean N× the configured budget.
  • Use one worker unless you have measured lease contention; the job table uses five-minute leases and heartbeats and can handle several workers, but SQLite write contention is the practical limit.
  • Long-lived MCP streams are cheapest on a single instance; a proxy with buffering disabled is mandatory.

8.6 Security checklist

  • FRONTEND_URL is HTTPS and matches the registered redirect URIs.
  • JWT_SECRET is random and stable, config.env is 0600, and both are backed up. It protects custom credentials, not OAuth tokens.
  • The SQLite file and its backups are encrypted at rest: provider access tokens (including OAuth tokens and some API keys) are stored in plain text in the database.
  • Rustiz binds 127.0.0.1 (or a private interface) behind a TLS proxy.
  • ALLOW_PRIVATE_NETWORK is unset unless the deployment is single-tenant and the network is trusted.
  • API keys are distributed over a secret manager, not chat or URLs.
  • TRUSTED_PROXY_HOPS matches the real proxy chain and the origin is firewalled to those proxies.
  • The /data volume and UPLOAD_DIRECTORY are writable only by the service user.
  • The object bucket is public only for media, and its write credentials are not exposed to clients.
  • Backups are encrypted and restore-tested.
  • RUST_LOG does not log request bodies containing credentials (the port redacts bodies stored in Errors, but proxy logs are your responsibility).