Operations

Production readiness

Checklist for running ctx| behind a real public origin.

Use this checklist before making a self-hosted deployment available to a team. The reference Compose stack is a starting point; production deployments should make the network boundary, persistence, secrets, and rollback process explicit.

Public origin

ctx| expects a single public backend origin for browser, REST, auth, and MCP traffic.

CheckWhy it matters
AUTH_BASE_URL is the public HTTPS originBetter Auth callbacks, generated links, OAuth issuer values, MCP auth, and connector callbacks depend on this value.
CTXPIPE_PUBLIC_APP_URL matches the public backend originThe UI uses this value at build time.
Browser users enter through the backendThe backend proxies the UI, keeping auth and API requests on the same origin.
AUTH_ALLOWED_ORIGINS includes only required extra originsAvoid broad CORS allowances.

TLS and proxying

Put a TLS-terminating proxy or platform load balancer in front of the backend. Expose only the backend origin publicly unless you have a specific operational reason to expose other services.

ServicePublic exposure
backendPublic HTTPS
uiPrivate; backend proxy should serve it
workerPrivate
codesearchPrivate
postgresPrivate
falkordb or graph databasePrivate

Telemetry export is outbound only. There is no collector to expose. Set OTEL_EXPORTER_OTLP_* to your own endpoint when you want traces, logs, or metrics to leave the app containers.

Callback URLs

Register callback and webhook URLs against your public origin.

IntegrationURL shape
Atlassian OAuth{AUTH_BASE_URL}/api/v1/integrations/atlassian/callback
Linear OAuth{AUTH_BASE_URL}/api/v1/integrations/linear/callback
Linear webhook{AUTH_BASE_URL}/api/v1/webhook/linear
GitHub App webhook{AUTH_BASE_URL}/api/v1/webhook/github/<connectionId>
Slack OAuth{AUTH_BASE_URL}/api/v1/connectors/slack/oauth/callback
Slack Events API{AUTH_BASE_URL}/api/v1/webhook/slack
Notion OAuth{AUTH_BASE_URL}/api/v1/connectors/notion/oauth/callback
Notion webhook{AUTH_BASE_URL}/api/v1/webhook/notion?provisioningToken=...
PagerDuty OAuth{AUTH_BASE_URL}/api/v1/integrations/pagerduty/callback
PagerDuty webhook{AUTH_BASE_URL}/api/v1/webhook/pagerduty
MCP{AUTH_BASE_URL}/mcp?orgSlug=<org-slug>
App auth/.auth/* routes under AUTH_BASE_URL

Persistence

Do not treat the reference Compose volumes as disposable in production.

StateProduction expectation
PostgresManaged backups, restore test, monitoring, and storage alerts
Graph databaseBackup or snapshot according to provider guidance
repo_cachePersistent volume if recloning large repositories is expensive
zoekt_index_deployPersistent volume if rebuilding indexes is expensive
SecretsStored in a secret manager or platform secret store, not committed files

Codesearch capacity

Keep codesearch at one replica. Zoekt shards, git clone cache, and SCIP artifacts are process-local. Extra worker replicas do not raise ingest throughput unless codesearch memory and the injected OPENWORKFLOW_CONCURRENCY / CODESEARCH_INDEXER_CONCURRENCY / CODESEARCH_INDEX_PIPELINE_CONCURRENCY values also grow. Compose deploy uses the small pair (indexer 1, pipelines 1, worker concurrency 6). AWS CDK injects the matching pair for small / medium / large.

Secret handling

Protect and rotate:

  • AUTH_SECRET
  • CONNECTION_SECRETS_ENCRYPTION_KEY, if set
  • GitHub App private keys and webhook secrets
  • Atlassian OAuth client secrets and Forge tokens
  • Slack client secret, signing secret, and stored bot-token encryption material
  • Linear OAuth client and webhook secrets, or the shared encryption key used to decrypt connection-stored Linear app secrets
  • Notion OAuth client and webhook secrets
  • Model provider API keys
  • SMTP credentials
  • OTLP exporter credentials

Changing encryption secrets

AUTH_SECRET and CONNECTION_SECRETS_ENCRYPTION_KEY can affect sessions and encrypted connector credentials. Plan rotation carefully and verify existing connectors after the change.

Connector readiness

Before inviting users:

  • Create or configure at least one GitHub App connection.
  • Confirm GitHub webhook delivery reaches the public backend origin.
  • If using Confluence, configure Atlassian OAuth and Forge install/provisioning.
  • If using Slack, set all three Slack app secrets, verify the OAuth callback and Events Request URL, and test installation in a non-development workspace when multi-workspace distribution is required.
  • If using Linear, register a Linear OAuth application (in the product UI, or optionally via LINEAR_* on backend and worker) and register the exact OAuth callback and webhook URLs.
  • Confirm backend and worker can reach api.linear.app.
  • If using Notion, configure NOTION_CLIENT_ID and NOTION_CLIENT_SECRET, register the exact OAuth redirect URL, and set NOTION_WEBHOOK_SECRET after the first webhook delivery.
  • If using PagerDuty, register the exact OAuth callback. Either save the client id and secret in the connector wizard, or configure PAGERDUTY_CLIENT_ID and PAGERDUTY_CLIENT_SECRET on backend and worker. ctx| creates the webhook subscription after authorization.
  • Confirm backend and worker can reach identity.pagerduty.com and api.pagerduty.com or api.eu.pagerduty.com.
  • Confirm the worker can run connector jobs.
  • Confirm codesearch can clone the expected repositories.
  • Confirm model provider credentials work for both chat and embedding calls.

Preflight checklist

  • curl https://<public-origin>/.status returns JSON with status: "ok".
  • Sign-in works using the enabled auth method.
  • A user can create or select an organization.
  • A repository can be added and reaches indexed state.
  • Chat or MCP can answer a question grounded in the repository.
  • Backend, worker, and codesearch logs are collected.
  • Postgres and graph database backups are configured.
  • Upgrade and rollback steps are written down for the current deployment shape.