# Public hostname served by Caddy. Point DNS here before first startup so # Let's Encrypt can issue a certificate. Self-hosted Web is served same-origin # from the server image at this address, so both the API and the Web # application answer here. bootstrap.sh derives BOTH API_BASE_URL and # FRONTEND_BASE_URL from this value (for example SITE_ADDRESS=proliferate.company.com # yields https://proliferate.company.com for each). SITE_ADDRESS=api.company.com # Optional explicit values may repeat the SITE_ADDRESS origin. Leave both blank # to derive them. preflight.sh rejects a different origin because self-hosted # Web and its API intentionally share one public authority. API_BASE_URL= FRONTEND_BASE_URL= # Optional public endpoint check after local API health passes. The AWS stack # sets this automatically so CloudFormation only succeeds once the advertised # HTTPS endpoint responds. PROLIFERATE_PUBLIC_HEALTHCHECK_URL= # Server image source for self-hosted deploys. PROLIFERATE_SERVER_IMAGE=ghcr.io/proliferate-ai/proliferate-server PROLIFERATE_SERVER_IMAGE_TAG=stable PROLIFERATE_HOST_BIN_DIR=/opt/proliferate/bin # Optional when pulling from private ECR. AWS_REGION= # Bundled PostgreSQL credentials and control-plane database URL. POSTGRES_DB=proliferate POSTGRES_USER=proliferate # Leave blank to auto-generate and persist on first bootstrap. POSTGRES_PASSWORD= # Core control-plane secrets. Leave blank to auto-generate and persist them on first bootstrap. JWT_SECRET= CLOUD_SECRET_KEY= PROLIFERATE_TELEMETRY_MODE=self_managed PROLIFERATE_ANONYMOUS_TELEMETRY_ENDPOINT=https://app.proliferate.com/api/v1/telemetry/anonymous PROLIFERATE_ANONYMOUS_TELEMETRY_DISABLED=false # Background jobs. These are dormant until the worker-tier deployment slice # starts Celery worker and Beat services. CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// CELERY_WORKER_QUEUES=periodic.default,default,notifications CELERY_TASK_ALWAYS_EAGER=false CELERY_TASK_TIME_LIMIT_SECONDS=3600 CELERY_TASK_SOFT_TIME_LIMIT_SECONDS=3300 REDBEAT_REDIS_URL=redis://redis:6379/0 REDBEAT_KEY_PREFIX=redbeat:proliferate: # Browser/Tauri origins that may call the control plane. CORS_ALLOW_ORIGINS=http://localhost:1420,http://127.0.0.1:1420,http://localhost:3000,http://127.0.0.1:3000,http://tauri.localhost,tauri://localhost # Instance admins. Comma-separated emails that always hold at least the admin # role in the instance organization. Asserted at account creation and at every # sign-in, so adding an email here and restarting the server is the # lockout-recovery path. Removing an email never demotes anyone. # WARNING: this reinstatement is deliberate lockout-recovery behavior. A listed # email that was removed from the instance in-product regains admin access at # its next sign-in. To offboard someone, remove them from this list as well as # from the instance organization. ADMIN_EMAILS= # Optional registration domain gate. Comma-separated email domains (for example # corp.example.com) that invited users must belong to before they can # self-register. Empty means invited emails at any domain may register. This is # a gate on top of invitations, never a grant: nobody registers without an # invitation, and it assigns no roles. ALLOWED_EMAIL_DOMAINS= # Desktop GitHub sign-in. Optional: when unset, the desktop app signs in with # email and password instead. Both must be set together (one alone advertises # a sign-in button that fails). Register exactly one OAuth callback URL with # GitHub: /auth/github/callback (this is a separate credential # set from the GitHub App below, which grants cloud-workspace repo access). GITHUB_OAUTH_CLIENT_ID= GITHUB_OAUTH_CLIENT_SECRET= # Deployment SSO (optional add-on). All fields below are required together to # get a usable OIDC connection: SSO_OIDC_CLIENT_ID, an issuer/discovery URL # (SSO_OIDC_ISSUER_URL or SSO_OIDC_DISCOVERY_URL, or the full static endpoint # set), and SSO_OIDC_CLIENT_SECRET (unless SSO_OIDC_TOKEN_ENDPOINT_AUTH_METHOD # is "none"). Register the IdP redirect URI as # /auth/sso/oidc/callback. SSO_ENABLED=false SSO_OIDC_CLIENT_ID= SSO_OIDC_CLIENT_SECRET= SSO_OIDC_ISSUER_URL= SSO_OIDC_DISCOVERY_URL= # First-time-user policy for SSO sign-ins. disabled (default) rejects unknown # users with an actionable sso_jit_disabled error; create_member # auto-provisions new users; existing_user allows sign-in only for users # already invited/registered by another path. A disabled policy with no # pre-provisioned admin can lock every SSO user out — see the doctor warning. SSO_JIT_POLICY=disabled SSO_DEFAULT_ROLE=member # Optional comma-separated allowlist of email domains for SSO JIT provisioning. SSO_ALLOWED_DOMAINS= # Set true ONLY for an internal/private/http IdP. This disables the HTTPS + # private-IP SSRF guard for all OIDC provider URLs; leave false for a public IdP. SSO_OIDC_ALLOW_PRIVATE_PROVIDER_URLS=false # GitHub App for cloud-workspace repository access (a separate credential set # from GITHUB_OAUTH_* sign-in above). Set all of these together to enable the # App; leave all blank to run without it. Provide the private key either # inline (GITHUB_APP_PRIVATE_KEY, \n-escaped PEM) or as a mounted file path # (GITHUB_APP_PRIVATE_KEY_PATH) — see GITHUB_APP_PRIVATE_KEY_HOST_PATH below # for the bundled bind-mount. The App needs four public routes reachable # through Caddy (already served by the default `handle { reverse_proxy # api:8000 }` route, no Caddyfile change needed): # GET /auth/github-app/user-authorization/callback # GET /auth/github-app/installation/callback # GET /integrations/github/callback (the App's Setup URL) # POST /v1/cloud/webhooks/github-app (webhook delivery) # A self-host-safe landing page is served at GET /auth/github-app/connected # with no extra config once the App is set up. GITHUB_APP_ID= GITHUB_APP_SLUG= GITHUB_APP_CLIENT_ID= GITHUB_APP_CLIENT_SECRET= GITHUB_APP_WEBHOOK_SECRET= # Base URL for the App's own callbacks; defaults to API_BASE_URL when unset. GITHUB_APP_CALLBACK_BASE_URL= # Inline PEM (escape newlines as \n). Leave blank if using the mounted-file # form below. GITHUB_APP_PRIVATE_KEY= # Mounted-file form: point this at the in-container path # /run/secrets/github-app/, and place the actual PEM on the host at # GITHUB_APP_PRIVATE_KEY_HOST_PATH (docker-compose.production.yml bind-mounts # that host directory read-only; install.sh creates the default path shown # below at install time). Leave both blank to use the inline form above # instead. GITHUB_APP_PRIVATE_KEY_PATH= GITHUB_APP_PRIVATE_KEY_HOST_PATH=/opt/proliferate/secrets/github-app # Transactional email (invitations). Optional: without RESEND_API_KEY, # invitation delivery is marked "skipped" and admins recover with the # always-available copy-link in the members UI. No SMTP path exists. RESEND_API_KEY= RESEND_FROM_EMAIL= # Instance branding and support routing shown in the connected Desktop app. # All optional; empty means the Desktop shows the connected origin host and no # operator support address. INSTANCE_NAME= INSTANCE_LOGO_URL= INSTANCE_SUPPORT_EMAIL= INSTANCE_SUPPORT_URL= # Cloud MCP. CLOUD_MCP_ENABLED=true CLOUD_MCP_OAUTH_CALLBACK_BASE_URL= CLOUD_MCP_SLACK_ENABLED=false # Set true only after the exact configured Slack app is Marketplace-qualified # and its release canary has passed. CLOUD_MCP_SLACK_DISTRIBUTION_READY=false CLOUD_MCP_SLACK_CLIENT_ID= CLOUD_MCP_SLACK_CLIENT_SECRET= CLOUD_MCP_SLACK_TOKEN_ENDPOINT_AUTH_METHOD=client_secret_post # Agent LLM gateway (optional LiteLLM add-on). Set AGENT_GATEWAY_ENABLED=true # and rerun bootstrap.sh/update.sh: they detect this flag and bring up the # profiled litellm + litellm-db services (and wait for litellm to report # healthy) automatically — no separate `docker compose --profile` command # needed. Also set the paired LITELLM_MASTER_KEY/AGENT_GATEWAY_LITELLM_MASTER_KEY, # LITELLM_POSTGRES_PASSWORD, AGENT_GATEWAY_LITELLM_PUBLIC_BASE_URL, and at # least one provider key below; preflight.sh blocks an incomplete combination # before it can take down a healthy instance. Docs: /docs/deployment/add-ons/model-gateway AGENT_GATEWAY_ENABLED=false AGENT_GATEWAY_LITELLM_BASE_URL=http://litellm:4000 # Public URL agents use to reach LiteLLM, for example https://llm.company.com AGENT_GATEWAY_LITELLM_PUBLIC_BASE_URL= # Generate with `openssl rand -hex 32`. AGENT_GATEWAY_LITELLM_MASTER_KEY must # be the exact same value as LITELLM_MASTER_KEY. AGENT_GATEWAY_LITELLM_MASTER_KEY= LITELLM_MASTER_KEY= LITELLM_POSTGRES_PASSWORD= AGENT_GATEWAY_DEFAULT_ORG_BUDGET_USD=0 # Provider keys the gateway routes centrally live with the LiteLLM service; # ANTHROPIC_API_KEY below also serves AI session titles. Add OPENAI_API_KEY / # XAI_API_KEY when you route those providers. OPENAI_API_KEY= XAI_API_KEY= # Cloud workspace provider (optional add-on). E2B_API_KEY and E2B_TEMPLATE_NAME # are a pair: set BOTH to enable cloud workspaces, or leave BOTH blank to run # without them. Setting E2B_API_KEY while E2B_TEMPLATE_NAME is empty makes the # API refuse to start (it restart-loops the whole control plane), so preflight.sh # blocks that combination before bootstrap/update touch the stack. Setting # this pair also brings up the bundled `redis` service (cloud materialization # lock) automatically via the cloud-workspaces compose profile — no separate # add-on step needed. # E2B_TEMPLATE_NAME is the published runtime template ref, for example # your-team/proliferate-runtime-cloud:production. Build one against your own # E2B account with `node scripts/build-template.mjs --alias # --rebuild-runtime` (needs Docker + zig + an E2B API key) — see # guides/deploying/self-hosted-deploy.md for the full recipe. E2B_API_KEY= E2B_TEMPLATE_NAME= # Optional observability. Self-managed deploys leave vendor Sentry empty in v1. SENTRY_DSN= SENTRY_ENVIRONMENT=self-hosted SENTRY_RELEASE=proliferate-server@self-hosted SENTRY_TRACES_SAMPLE_RATE=1.0 SUPPORT_SLACK_WEBHOOK_URL= SUPPORT_REPORT_S3_BUCKET= SUPPORT_REPORT_S3_PREFIX=support/reports SUPPORT_REPORT_S3_REGION= SUPPORT_REPORT_UPLOAD_URL_EXPIRES_SECONDS=900 SUPPORT_REPORT_DIAGNOSTICS_MAX_BYTES=26214400 SUPPORT_REPORT_ATTACHMENT_MAX_BYTES=26214400 SUPPORT_REPORT_TOTAL_ATTACHMENT_MAX_BYTES=104857600 SIGNUPS_SLACK_WEBHOOK_URL= BILLING_POSITIVE_SLACK_WEBHOOK_URL= BILLING_NEGATIVE_SLACK_WEBHOOK_URL= CUSTOMERIO_SITE_ID= CUSTOMERIO_API_KEY= CUSTOMERIO_APP_API_KEY= # Set to a sender address on a sending domain you own and have verified in # Customer.io. The hosted Proliferate workspace uses hello@proliferate.com; # self-hosted operators must use their own verified domain. CUSTOMERIO_FROM_EMAIL= CUSTOMERIO_WELCOME_TRANSACTIONAL_MESSAGE_ID= ANTHROPIC_API_KEY= AI_MAGIC_SESSION_TITLE_MODEL=claude-haiku-4-5-20251001 # Required for self-hosted cloud workspace provisioning. Place Linux runtime # bundle binaries on the host inside PROLIFERATE_HOST_BIN_DIR, or set # RUNTIME_BINARY_URL to a release tarball that contains all three binaries. CLOUD_RUNTIME_SOURCE_BINARY_PATH= CLOUD_WORKER_SOURCE_BINARY_PATH= CLOUD_SUPERVISOR_SOURCE_BINARY_PATH= RUNTIME_BINARY_URL= # Optional checksum verification for downloaded runtime archives. RUNTIME_BINARY_SHA256= RUNTIME_BINARY_SHA256_URL= # Hosted-product only. Self-managed and local-dev omit runtime Sentry injection. CLOUD_RUNTIME_SENTRY_DSN= CLOUD_RUNTIME_SENTRY_ENVIRONMENT= CLOUD_RUNTIME_SENTRY_RELEASE= CLOUD_RUNTIME_SENTRY_TRACES_SAMPLE_RATE=1.0 CLOUD_TARGET_SENTRY_DSN= CLOUD_TARGET_SENTRY_ENVIRONMENT= # Emergency component-specific release overrides; normally empty (each binary # stamps its own @+ release at build time). CLOUD_WORKER_SENTRY_RELEASE= CLOUD_SUPERVISOR_SENTRY_RELEASE= CLOUD_TARGET_SENTRY_TRACES_SAMPLE_RATE=1.0