Skip to content

Self Hosting

Wuthrich Julien edited this page Aug 22, 2026 · 1 revision

Self-Hosting

Runbook: guides/DEPLOY.md (prod guards, every env var, worker pool, backups, post-deploy verification). Docs-site page: Self-hosting. Railway by hand: deploy/railway/README.md.

One click

Deploy on Railway

Provisions API, worker, UI, Postgres (pgvector), ClickHouse, Redis and MinIO with volumes and private networking. Migrations + seeding run on first deploy. You'll be asked for SESSION_SECRET and SECRETS_ENCRYPTION_KEYopenssl rand -hex 32 each.

Docker Compose (any host)

docker compose up -d --build --wait runs the same seven services. The compose file is a dev stack by default (AUTH_MODE=dev, seeded tracely_dev_key) — harden it before exposing it.

The minimum for production

Variable Why
TRACELY_ENV=prod Turns on the refuse-to-boot guards, tightens CORS, skips dev-key seeding
AUTH_MODE=local + SESSION_SECRET (≥32 chars) — or AUTH_MODE=clerk + CLERK_ISSUER Human auth. Prod refuses to boot in dev mode or with tracely_dev_key in the DB
SECRETS_ENCRYPTION_KEY (≥32 chars, same value on backend and worker) Encrypts each workspace's OpenRouter key at rest. Unset → the app refuses to store keys rather than persisting plaintext
DATABASE_URL, ALEMBIC_DATABASE_URL, CLICKHOUSE_*, REDIS_URL, S3_* The five stores
FRONTEND_ORIGIN, APP_BASE_URL (both backend and worker) CORS allow-list; invite and alert links
NEXT_PUBLIC_AUTH_MODE on the frontend Must match the backend's AUTH_MODE or login loops
CELERY_POOL=prefork, CELERY_CONCURRENCY=4 Real worker concurrency (local dev runs solo)

Optional: RESEND_API_KEY + EMAIL_FROM (invites are otherwise "share this link"), SENTRY_DSN, and the hosted-cloud billing flags (BILLING_ENABLED, ALLOW_PUBLIC_SIGNUP, REQUIRE_PROJECT_LLM_KEY) which are all off by default.

LLM keys: customers bring their own. Each workspace sets its OpenRouter key in Settings; a workspace without one is simply an LLM-disabled deployment (structural evaluators still run). Server-wide OPENROUTER_API_KEY only serves the in-app assistant and out-of-project scripts.

Operating it

  • Backups are the one thing Tracely can't do for you — enable Postgres + ClickHouse snapshots in your provider and do a restore test once.
  • Beat: run exactly one Celery beat (nightly chat prune, threshold alerts, self-check). /health/queue reports queue depth including Celery's unacked.
  • The worker does not hot-reload — restart it after deploying worker/eval code.
  • Railway specifics: pre-deploy/start commands run with no shell, so chain steps with sh -c "… && …"; keep Postgres on a volume or it runs ephemeral.

Clone this wiki locally