# Database POSTGRES_DB=multica POSTGRES_USER=multica POSTGRES_PASSWORD=multica POSTGRES_PORT=5432 DATABASE_URL=postgres://multica:multica@localhost:5432/multica?sslmode=disable # Optional pgxpool tuning. Defaults are 25 / 5 per pod and are usually fine. # You can also set pool_max_conns / pool_min_conns as query params on # DATABASE_URL; env vars below take precedence over URL params. # DATABASE_MAX_CONNS=25 # DATABASE_MIN_CONNS=5 # Server # APP_ENV gates production safety checks. Docker self-host pins APP_ENV to # "production" by default. Local dev can leave it unset. # See SELF_HOSTING.md for the full login setup. APP_ENV= # Optional local/testing shortcut. Empty by default, so there is no fixed # verification code. Without RESEND_API_KEY, generated codes print to stdout. # If you need deterministic local automation, set a 6-digit value such as # 888888 and keep APP_ENV non-production. This is ignored when APP_ENV=production. MULTICA_DEV_VERIFICATION_CODE= PORT=8080 # Prometheus metrics are disabled by default. When enabled, bind to loopback # unless you protect the listener with private networking, allowlists, or # proxy auth. Do not expose this endpoint through the public app/API ingress. # HTTP request metrics start accumulating only when this listener is enabled. # METRICS_ADDR=127.0.0.1:9090 JWT_SECRET=change-me-in-production MULTICA_SERVER_URL=ws://localhost:8080/ws MULTICA_APP_URL=http://localhost:3000 MULTICA_DAEMON_CONFIG= MULTICA_WORKSPACE_ID= MULTICA_DAEMON_ID= MULTICA_DAEMON_DEVICE_NAME= MULTICA_DAEMON_POLL_INTERVAL=3s MULTICA_DAEMON_HEARTBEAT_INTERVAL=15s MULTICA_CODEX_PATH=codex MULTICA_CODEX_MODEL= MULTICA_CODEX_WORKDIR= MULTICA_CODEX_TIMEOUT=20m # Self-host image channel # Default stable release channel. Pin to an exact release like v0.2.4 if you # want to stay on a specific version. If the selected tag has not been # published to GHCR yet, use make selfhost-build / the build override instead. MULTICA_IMAGE_TAG=latest MULTICA_BACKEND_IMAGE=ghcr.io/multica-ai/multica-backend MULTICA_WEB_IMAGE=ghcr.io/multica-ai/multica-web # Email (Resend) # For local/dev use, leave RESEND_API_KEY empty — generated codes print to stdout. # For production, set your Resend API key and change RESEND_FROM_EMAIL to a domain verified in your Resend account. RESEND_API_KEY= RESEND_FROM_EMAIL=noreply@multica.ai # Google OAuth # The web login page reads GOOGLE_CLIENT_ID from /api/config at runtime, so # changing it only requires restarting the backend / compose stack. No web # rebuild is needed. GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= GOOGLE_REDIRECT_URI=http://localhost:3000/auth/callback # S3 / CloudFront S3_BUCKET= S3_REGION=us-west-2 CLOUDFRONT_KEY_PAIR_ID= CLOUDFRONT_PRIVATE_KEY_SECRET=multica/cloudfront-signing-key CLOUDFRONT_PRIVATE_KEY= CLOUDFRONT_DOMAIN= # COOKIE_DOMAIN — optional Domain attribute on session + CloudFront cookies. # Leave empty for single-host deployments (localhost, LAN IP, or a single # hostname) — session cookies become host-only, which is what the browser # wants. Only set it when the frontend and backend sit on different # subdomains of one registered domain (e.g. ".example.com"). Do NOT set it # to an IP address: RFC 6265 forbids IP literals in the cookie Domain # attribute and browsers silently drop such cookies. COOKIE_DOMAIN= # Local file storage (fallback when S3_BUCKET is not set) LOCAL_UPLOAD_DIR=./data/uploads LOCAL_UPLOAD_BASE_URL=http://localhost:8080 # Security # Comma-separated list of allowed origins for CORS and WebSocket connections. # Defaults to localhost dev origins when unset. # Example: ALLOWED_ORIGINS=https://app.multica.ai,https://staging.multica.ai ALLOWED_ORIGINS= # Realtime metrics endpoint (/health/realtime) access control. See MUL-1342. # When unset, the endpoint only serves direct loopback (127.0.0.1 / ::1) # callers with no forwarding headers and returns 404 to everything else — # safe for local dev. Any deployment behind a reverse proxy (Caddy / Nginx # terminating TLS in front of localhost:8080) MUST set this token, since # proxied requests look like loopback at the Go layer; with no token, those # requests are refused with 404. Pass the token as # `Authorization: Bearer `. # REALTIME_METRICS_TOKEN= # Frontend FRONTEND_PORT=3000 FRONTEND_ORIGIN=http://localhost:3000 # Leave empty — auto-derived from page origin in browser, set by Makefile for local dev. # Only set explicitly if frontend and backend are on different domains. NEXT_PUBLIC_API_URL= NEXT_PUBLIC_WS_URL= # Remote API (optional) — set to proxy local frontend to a remote backend # Leave empty to use local backend (localhost:8080) # REMOTE_API_URL=https://multica-api.copilothub.ai # ==================== Self-hosting: Control Signups (fixes #930) ==================== # Set to "false" to completely disable new user signups (recommended for private instances) ALLOW_SIGNUP=true # The web UI reads ALLOW_SIGNUP from /api/config at runtime, so toggling this # only requires restarting the backend / compose stack — not rebuilding web. # It is not hot-reloaded. # Optional: Only allow emails from these domains (comma-separated) ALLOWED_EMAIL_DOMAINS= # Optional: Only allow these exact email addresses (comma-separated) ALLOWED_EMAILS= # ==================== Analytics (PostHog) ==================== # Product analytics events feed the acquisition → activation → expansion funnel. # Leave POSTHOG_API_KEY empty for local dev / self-hosted instances; the server # will run a no-op analytics client and ship nothing. See docs/analytics.md. POSTHOG_API_KEY= POSTHOG_HOST=https://us.i.posthog.com # Force the no-op client even when POSTHOG_API_KEY is set (CI / opt-out). ANALYTICS_DISABLED=