Configuration

Configuration

Configure Docker Compose, environment variables, and connector secrets for self-hosted ctx|.

Configuration is environment-driven. Set only the values your deployment needs, but treat the required auth, database, model, and public-origin values as production secrets.

Runtime requirements

  • A supported deployment path: Docker Compose, the repository Terraform stack (Railway + Neon), or AWS CDK
  • PostgreSQL 17; the reference Compose image is pgvector on Postgres 17
  • A graph database; FalkorDB is included in the reference Compose stack
  • An SMTP provider for transactional email
  • An OpenRouter, Azure, Bedrock, or OpenAI-compatible model provider
  • A public HTTPS origin for production auth callbacks, webhooks, MCP, and Forge remotes

Docker Compose

Clone the repository and copy the example environment file:

git clone https://github.com/ctxpipe-ai/ctxpipe.git
cd ctxpipe
cp docker-compose.env.example .env

Edit .env with your values. The full production-style stack is the Compose deploy profile:

pnpm start

The deploy profile starts Postgres, FalkorDB, migrator, backend, worker, UI, and codesearch. It does not start an OpenTelemetry collector. The backend listens on the public app port and proxies the UI.

Required variables

VariableDescription
DATABASE_URLPostgreSQL connection string, for example postgresql://user:pass@host:5432/db
AUTH_SECRETRandom 32+ character string for session signing. Generate with openssl rand -hex 32.
AUTH_BASE_URLPublic URL of your ctx| instance, for example https://ctx.example.com
CTXPIPE_PUBLIC_APP_URLPublic backend URL baked into the UI image. Usually the same value as AUTH_BASE_URL.
MODEL_PROVIDER_API_KEYAPI key for your configured model provider

Email

VariableDescription
SMTP_CONNECTION_URLSMTP connection URL, for example smtps://user:[email protected]:465
EMAIL_FROM_ADDRESSFrom address for transactional email, for example [email protected]

Social sign-in

All social providers are optional. Omit the variables to disable that provider.

VariableDescription
GITHUB_CLIENT_IDGitHub OAuth app client ID
GITHUB_CLIENT_SECRETGitHub OAuth app client secret
GOOGLE_CLIENT_IDGoogle OAuth client ID
GOOGLE_CLIENT_SECRETGoogle OAuth client secret
MICROSOFT_CLIENT_IDMicrosoft Entra application client ID
MICROSOFT_CLIENT_SECRETMicrosoft Entra client secret

See Authentication for OAuth and session behavior.

Models and embeddings

VariableDescription
MODEL_PROVIDEROptional. openai-like default, openrouter, azure, or bedrock.
MODEL_PROVIDER_API_KEYAPI key for OpenAI-compatible providers. Omit for native Bedrock IAM.
MODEL_PROVIDER_URLOptional for openai-like and openrouter; required for Azure; not used by native Bedrock.
MODEL_BEDROCK_AWS_REGIONOptional explicit region for native Bedrock; otherwise use the AWS runtime region.
MODEL_FAST_NAME, MODEL_MEDIUM_NAME, MODEL_HIGH_NAMEOptional model names per tier.
MODEL_EMBEDDING_NAMEOptional embedding model ID.

See Model configuration for provider-specific examples and embedding requirements.

Graph database

VariableDescription
GRAPH_DB_PROVIDEROptional. Selects graph provider strategy.
GRAPH_DB_URIFalkorDB Redis URI or Bolt URI for another supported graph database.
GRAPH_DB_USER, GRAPH_DB_PASSWORDOptional credentials for providers that require them.

See Graph databases for provider support and tenancy behavior.

GitHub App connector

Repository connectors use a deployment-owned GitHub App. The in-product wizard stores its ID, PEM private key, and webhook secret encrypted for the connection.

VariableDescription
GITHUB_APP_IDOptional after migrations. GitHub App numeric ID.
GITHUB_PRIVATE_KEYOptional after migrations. PEM private key for the App.
GITHUB_WEBHOOK_SECRETOptional after migrations. Also used for the legacy webhook route.
GITHUB_APP_SLUGOptional. Public app slug used for default install URLs.
CONNECTION_SECRETS_ENCRYPTION_KEYOptional 64-character hex key. When unset, encryption derives from AUTH_SECRET.

The wizard reserves the connection-specific webhook URL and provides the exact value to paste into GitHub.

OAuth sign-in is separate

GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are for signing in with GitHub. GitHub App credentials are for repository installation and webhook access.

See GitHub for App registration, permissions, events, credentials, installation, and end-to-end verification.

Atlassian and Confluence

Self-hosted Confluence uses the same product wizard as fully managed ctx|, but your deployment or organization must provide Atlassian and Forge settings first.

VariableDescription
ATLASSIAN_CLIENT_ID, ATLASSIAN_CLIENT_SECRETOptional global Atlassian 3LO app for account linking. If unset, each Forge connection can store its own 3LO credentials through the wizard.
CONFLUENCE_FORGE_INSTALL_URLOptional deployment-wide Forge install URL fallback when a Forge connection has no install URL in connections.config.

See Confluence & Atlassian for the full operator flow.

Slack

Self-hosted Slack uses one deployment-owned Slack app. Organizations authorize that app; they do not create per-tenant Slack apps or Event Subscription URLs.

VariableDescription
SLACK_CLIENT_ID, SLACK_CLIENT_SECRETSlack app OAuth credentials. Required to enable the Slack connector.
SLACK_SIGNING_SECRETVerifies Event Subscription requests (X-Slack-Signature).
SLACK_REDIRECT_URIOptional. Override when the public OAuth callback differs from {AUTH_BASE_URL}/api/v1/connectors/slack/oauth/callback.

Set the client ID, client secret, and signing secret together, then restart or redeploy backend. Backend and worker must share the same AUTH_SECRET and, when configured, CONNECTION_SECRETS_ENCRYPTION_KEY so encrypted Slack bot tokens remain usable by background capture jobs.

Set the Slack Event Subscriptions Request URL to:

https://<public-origin>/api/v1/webhook/slack

See Slack for scopes, app_mention Events, and intent-based thread capture.

Linear

Linear can store the OAuth application and webhook signing secret on the connection (Register in the product UI). LINEAR_* is an optional deployment-wide fallback.

VariableDescription
LINEAR_CLIENT_ID, LINEAR_CLIENT_SECRETOptional shared Linear OAuth application credentials. When both are set, the wizard skips Register.
LINEAR_REDIRECT_URIOptional exact callback override. Defaults to {AUTH_BASE_URL}/api/v1/integrations/linear/callback.
LINEAR_WEBHOOK_SECRETOptional shared signing secret for /api/v1/webhook/linear. Per-connection secrets are stored on the row.

See Linear for application registration, webhook subscriptions, preview limitations, and troubleshooting.

Notion

Notion uses one deployment-owned public integration and one deployment webhook subscription.

VariableDescription
NOTION_CLIENT_ID, NOTION_CLIENT_SECRETPublic integration OAuth credentials. Both are required to enable the connector.
NOTION_REDIRECT_URIOptional exact callback override. Defaults to {AUTH_BASE_URL}/api/v1/connectors/notion/oauth/callback.
NOTION_WEBHOOK_SECRETVerification token shown by Notion after the first webhook delivery. Required for signed updates.

Put the OAuth credentials on every service that performs token refresh or connector work, then register the single deployment webhook. See Notion for provisioning and verification.

PagerDuty

PagerDuty can use a deployment-owned OAuth application. After a user authorizes an account, ctx| creates the signed webhook subscription. These variables are an optional hosted-style shortcut; self-host can save the app on the connection in the setup wizard instead.

VariableDescription
PAGERDUTY_CLIENT_ID, PAGERDUTY_CLIENT_SECRETOptional shared PagerDuty OAuth application. When unset, save client id and secret on the connection in the wizard.
PAGERDUTY_REDIRECT_URIOptional exact callback override. Defaults to {AUTH_BASE_URL}/api/v1/integrations/pagerduty/callback.

There is no PAGERDUTY_WEBHOOK_SECRET. Per-subscription signing secrets are stored encrypted on the connection.

See PagerDuty for application registration and verification.

Observability

Telemetry is off until you set it. ctx| does not ship a collector, Langfuse, or ClickStack in the Compose deploy profile or in @ctxpipe/aws-cdk. Unset values keep logs on stdout and do not start trace or metric export. Empty values are treated as unset.

Point the signal URLs at your own OTLP/HTTP backend. Export starts from these variables. Include the signal path on each URL.

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otel.example.com/v1/traces
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://otel.example.com/v1/logs
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://otel.example.com/v1/metrics
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer xxx
VariableDescription
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTTraces URL, including /v1/traces. Trace export stays off when this is unset.
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTLogs URL, including /v1/logs. Unset keeps logs on stdout.
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTMetrics URL, including /v1/metrics.
OTEL_EXPORTER_OTLP_HEADERSOptional headers, for example Authorization=Bearer xxx.
OTEL_SERVICE_NAMEResource service.name. Compose and CDK set backend, openworkflow, ui, and codesearch per container. Compose does not apply a shared name from the root .env.
OTEL_RESOURCE_ATTRIBUTESExtra resource attributes, for example deployment.environment=production.

deployment.environment on backend traces, metrics, and logs, the Langfuse environment tag, codesearch, and the UI relay is RAILWAY_ENVIRONMENT_NAME when that is set, otherwise deployment.environment from OTEL_RESOURCE_ATTRIBUTES, otherwise production when NODE_ENV=production, otherwise development. Backend and codesearch also set service.namespace=ctxpipe. Codesearch always exports service.name codesearch.

LLM spans are OpenTelemetry spans. The apps do not read LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, or LANGFUSE_HOST. A Langfuse project accepts traces at https://<your-langfuse>/api/public/otel/v1/traces with Authorization=Basic <base64(publicKey:secretKey)> in OTEL_EXPORTER_OTLP_HEADERS. @ctxpipe/aws-cdk takes one base otel.endpoint and appends /v1/traces, /v1/logs, and /v1/metrics; see AWS.

Browser telemetry

The UI enables browser telemetry only when OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is set on the UI server. The browser posts traces to the same origin at /.otel/v1/traces. The relay also accepts /.otel/v1/logs, but the SDK does not use it: replay is off, and console capture is emitted as spans. The UI server forwards traces to OTEL_EXPORTER_OTLP_TRACES_ENDPOINT and logs to OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, using OTEL_EXPORTER_OTLP_HEADERS. When the traces endpoint is unset, the browser SDK does not start. A signal whose endpoint is unset returns 204.

Advanced

VariableDescription
AUTH_ISSUEROverride the OAuth issuer claim. Defaults to AUTH_BASE_URL.
AUTH_ALLOWED_ORIGINSComma-separated list of allowed CORS origins for auth endpoints.
CODESEARCH_URLURL of the codesearch service when running separately.
OPENWORKFLOW_CONCURRENCYIn-flight OpenWorkflow runs per worker process. Default 4 when unset. CDK/Railway/Compose inject size-based values.
CODESEARCH_INDEXER_CONCURRENCYMax concurrent Zoekt/SCIP child processes on codesearch, and SCIP HTTP batch size on the worker. Default 2.
CODESEARCH_INDEX_PIPELINE_CONCURRENCYMax distinct repos with in-flight OpenWorkflow index-phase HTTP (clone included). Default 2. Codesearch returns 429 when full.

Railway

ctx| can be deployed on Railway with prebuilt images from GitHub Container Registry. A typical flow is:

  1. Build and push service images from CI:
    • ghcr.io/ctxpipe-ai/backend:<sha>
    • ghcr.io/ctxpipe-ai/worker:<sha>
    • ghcr.io/ctxpipe-ai/ui:<sha>
    • ghcr.io/ctxpipe-ai/codesearch:<sha>
  2. Configure Railway services to use image sources.
  3. Set environment variables and secrets in Railway.
  4. Roll production by changing service image tags to the intended commit SHA.