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.
| Check | Why it matters |
|---|---|
AUTH_BASE_URL is the public HTTPS origin | Better Auth callbacks, generated links, OAuth issuer values, MCP auth, and connector callbacks depend on this value. |
CTXPIPE_PUBLIC_APP_URL matches the public backend origin | The UI uses this value at build time. |
| Browser users enter through the backend | The backend proxies the UI, keeping auth and API requests on the same origin. |
AUTH_ALLOWED_ORIGINS includes only required extra origins | Avoid 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.
| Service | Public exposure |
|---|---|
backend | Public HTTPS |
ui | Private; backend proxy should serve it |
worker | Private |
codesearch | Private |
postgres | Private |
falkordb or graph database | Private |
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.
| Integration | URL 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.
| State | Production expectation |
|---|---|
| Postgres | Managed backups, restore test, monitoring, and storage alerts |
| Graph database | Backup or snapshot according to provider guidance |
repo_cache | Persistent volume if recloning large repositories is expensive |
zoekt_index_deploy | Persistent volume if rebuilding indexes is expensive |
| Secrets | Stored 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_SECRETCONNECTION_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_IDandNOTION_CLIENT_SECRET, register the exact OAuth redirect URL, and setNOTION_WEBHOOK_SECRETafter 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_IDandPAGERDUTY_CLIENT_SECRETon backend and worker. ctx| creates the webhook subscription after authorization. - Confirm backend and worker can reach
identity.pagerduty.comandapi.pagerduty.comorapi.eu.pagerduty.com. - Confirm the worker can run connector jobs.
- Confirm
codesearchcan clone the expected repositories. - Confirm model provider credentials work for both chat and embedding calls.
Preflight checklist
curl https://<public-origin>/.statusreturns JSON withstatus: "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.
Related pages
Environment variables and connector setup.
Logs, health, backups, and recovery.
Deployment-owned App registration, permissions, and webhooks.
Atlassian callbacks, Forge, and sync.
Slack app scopes, app_mention Events, deployment secrets, and troubleshooting.
Linear OAuth, signed webhooks, and end-to-end verification.
Notion OAuth, webhook signing, and end-to-end verification.
PagerDuty OAuth, automatic webhooks, and end-to-end verification.