Skip to main content

Deployment

How to take a Titan app from pnpm dev to production. Four paths covered in detail, plus the cross-cutting concerns.

Choose your path

WhereUse
One box, you own itDocker Compose — daemon + apps + infra in one stack
Container orchestratorKubernetes — daemon as a stateful pod, apps as deployments
Platform-as-a-ServiceFly.io / Railway / Render — opinionated, fast to ship
Bare-metal / VMsystemd — daemon as a system service

For dev / staging / prod parity, run the same omnitron.config.ts across environments. Only secrets + scale parameters change per deploy target.

Cross-cutting concerns

What you ship

A production deployment carries:

  1. Compiled app codedist/ for each app.
  2. omnitron.config.ts — the ecosystem config.
  3. Per-app config/default.json — declarative infra.
  4. Static webapp bundle (optional) — apps/omnitron/webapp/dist/.
  5. Migrationsmigrations/*.sql.

That's it. No generated client code, no schema sync artefacts, no shipped node_modules.

What you provide at the target

  • Node.js 22+.
  • PostgreSQL (managed or self-hosted) — connection string in env.
  • Redis (managed or self-hosted) — connection string in env.
  • Object storage (S3 / MinIO) — credentials in env.
  • Secrets manager (optional) — Omnitron's encrypted store works standalone; for prod prefer a real secret manager.

Environment variables — the canonical set

VariablePurpose
NODE_ENV'production'
OMNITRON_HOMEOverride ~/.omnitron/ location
DATABASE_URLPostgres connection string
REDIS_URLRedis connection string
JWT_SECRETSigning key — long random; from secret manager
OMNITRON_TOKENOperator token for remote daemon ops (optional)
<APP>_*Per-app overrides (matches envPrefix in bootstrap.ts)

Anything in omnitron.config.ts can be derived from env at boot via ConfigService — favour env over config files for per-environment values.

Logs and metrics

  • Logs stream to stdout (pino JSON) — ingest with your log aggregator's stdin-tail or sidecar.
  • Metrics scrape via the Omnitron daemon's /metrics endpoint or push to a backend via titan-telemetry-relay.
  • Health probes — point your platform's liveness/readiness at /healthz / /readyz served by titan-health.

Secrets

Three options, in order of preference:

  1. Cloud secret manager (AWS Secrets Manager, GCP Secret Manager, Vault) — inject as env at pod / container boot.
  2. Encrypted file (~/.omnitron/secrets.enc) — works without external dependencies; rotate the passphrase via env.
  3. Plain env vars — fine for non-sensitive config, not for credentials.

Never commit secrets to omnitron.config.ts or config/default.json.

Migrations

# In the deploy script, before starting the daemon:
omnitron infra migrate
# or for one app:
omnitron infra migrate api

Migrations run inside a Postgres advisory lock — concurrent deploys are safe; only one will run, others wait.

Backups

# Manual:
omnitron backup create

# Scheduled (in omnitron.config.ts or via CLI):
omnitron backup schedule create main --cron '0 2 * * *'

Backups land in ~/.omnitron/backups/ by default; configure S3 destination in the daemon config for off-host storage.

Zero-downtime deploys

The reload command cycles workers one-by-one:

omnitron reload api

In module-worker mode, the worker pool maintains capacity throughout the reload. In classic mode, a new bootstrap is forked side-by-side; the old one drains.

For blue/green or canary, the deploy command supports --strategy blue-green and --strategy canary.

Multi-region

StrategyPattern
One cluster per region (recommended)Each region elects its own leader; cross-region calls via ingress
Single global clusterAll daemons peer; sensitive to partition
Fleet without clusterEach daemon independent; addressed by alias

See Cluster + Fleet / Multi-region patterns.

Observability checklist

  • Logs → SIEM / log aggregator.
  • Metrics → Prometheus / managed metrics backend.
  • Traces → OTel collector (if titan-tracing configured).
  • Health probes → load balancer.
  • Uptime monitoring → external pinger of /healthz.
  • Error reporting → Sentry via netron-browser middleware.
  • Alerts → OmnitronAlerts with delivery webhooks.

Security checklist (deploy time)

  • TLS terminated at the gateway / load balancer (not the app).
  • Strong JWT_SECRET, rotated quarterly.
  • Omnitron TCP port (9700) firewalled to internal only.
  • Database password from secret manager, never env literal.
  • CORS allowlist limited to known origins.
  • CSP header on webapp.
  • Rate limits configured per public endpoint.
  • Audit logs going to append-only sink.

See Auth & RBAC and the per-module Security checklist.

Rollback

# Roll back the last deploy:
omnitron rollback api

# Or to a specific version:
omnitron rollback api --version v1.4.2

Configure retention of previous deploy artefacts in omnitron.config.ts:

deployment: {
retain: 5, // keep last 5 versions for rollback
versionTag: 'git-sha', // 'git-sha' | 'semver' | 'timestamp'
}

Read the per-target guides

See also