mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-16 19:29:26 +02:00
279 lines
13 KiB
Plaintext
279 lines
13 KiB
Plaintext
# 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
|
|
# Docker Compose consumes flat port values. Set BACKEND_PORT directly to
|
|
# override the backend host port.
|
|
BACKEND_PORT=8080
|
|
# Optional aliases for local/self-host backend port helpers outside compose.
|
|
# API_PORT=8080
|
|
# SERVER_PORT=8080
|
|
FRONTEND_PORT=3000
|
|
# Derived by docker-compose.selfhost.yml / local scripts from FRONTEND_PORT.
|
|
# Set explicitly only when serving frontend on a different origin/domain.
|
|
FRONTEND_ORIGIN=http://localhost:${FRONTEND_PORT}
|
|
# 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
|
|
# Derived by Makefile / local scripts from the backend port.
|
|
# Set explicitly only when the daemon reaches the API through a different URL.
|
|
# MULTICA_SERVER_URL=ws://localhost:8080/ws
|
|
# Derived by docker-compose.selfhost.yml / local scripts from FRONTEND_ORIGIN.
|
|
# Set explicitly only when the app's public URL differs from local frontend.
|
|
MULTICA_APP_URL=${FRONTEND_ORIGIN}
|
|
# Public URL the API is reachable at from the open internet (no trailing
|
|
# slash). Used to mint absolute webhook URLs for autopilot webhook
|
|
# triggers and to show correct daemon setup commands in the web UI. Leave
|
|
# unset behind a same-origin reverse proxy or for plain localhost dev —
|
|
# the frontend will compose the URL from window.origin + webhook_path in
|
|
# that case. Headers are intentionally not used to derive this value, to
|
|
# avoid Host / X-Forwarded-Host spoofing when a self-hosted reverse proxy
|
|
# is not hardened.
|
|
MULTICA_PUBLIC_URL=
|
|
# Comma-separated CIDR list of reverse proxies whose X-Forwarded-For /
|
|
# X-Real-IP headers the per-IP webhook rate limiter is allowed to trust.
|
|
# Empty (the default) means "trust no headers" — the limiter uses
|
|
# r.RemoteAddr only, which is the safe shape when the backend is
|
|
# exposed directly. Set this when running behind nginx/Caddy/Cloudflare:
|
|
# e.g. "127.0.0.1/32" for a same-host reverse proxy, or the CDN's
|
|
# announced ranges for cloud deployments.
|
|
MULTICA_TRUSTED_PROXIES=
|
|
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
|
|
# Two delivery options - only one needs to be configured:
|
|
#
|
|
# Option A: Resend (SaaS, recommended for cloud deployments)
|
|
# Set RESEND_API_KEY to a key from resend.com and verify your sending domain there.
|
|
# For local/dev use, leave RESEND_API_KEY empty - codes print to stdout. To
|
|
# accept a fixed local code, also set MULTICA_DEV_VERIFICATION_CODE above
|
|
# (ignored when APP_ENV=production).
|
|
RESEND_API_KEY=
|
|
RESEND_FROM_EMAIL=noreply@multica.ai
|
|
#
|
|
# Option B: SMTP relay (for self-hosted / on-premise deployments)
|
|
# Takes priority over Resend when SMTP_HOST is set.
|
|
# Supports unauthenticated relay (leave SMTP_USERNAME empty) and authenticated SMTP.
|
|
# Set SMTP_TLS_INSECURE=true only for private CA or self-signed certificates.
|
|
# SMTP_TLS controls the TLS mode:
|
|
# - unset / "starttls" (default): plaintext connect, upgrade via STARTTLS.
|
|
# - "implicit" (aliases: "smtps", "ssl"): TLS handshake on connect (SMTPS).
|
|
# Required by providers that only offer port 465 and do not advertise
|
|
# STARTTLS (e.g. Aliyun enterprise mail). Auto-enabled when SMTP_PORT=465
|
|
# and SMTP_TLS is unset.
|
|
# SMTP_EHLO_NAME is the EHLO/HELO name announced to the relay. Defaults to the
|
|
# machine hostname; set a real FQDN when a strict relay (e.g. Google Workspace
|
|
# smtp-relay.gmail.com) rejects the default and the connection drops as an EOF.
|
|
SMTP_HOST=
|
|
SMTP_PORT=25
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
SMTP_TLS_INSECURE=false
|
|
SMTP_TLS=
|
|
SMTP_EHLO_NAME=
|
|
|
|
# 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=
|
|
# Derived by docker-compose.selfhost.yml / local scripts from FRONTEND_ORIGIN.
|
|
# Set explicitly only when your OAuth callback URL differs from local frontend.
|
|
GOOGLE_REDIRECT_URI=${FRONTEND_ORIGIN}/auth/callback
|
|
|
|
# S3 / CloudFront
|
|
# S3_BUCKET — bucket NAME only (e.g. "my-bucket"). Do NOT include the
|
|
# ".s3.<region>.amazonaws.com" suffix; the server builds the public URL
|
|
# from S3_BUCKET + S3_REGION. S3_REGION must match the bucket's real region.
|
|
S3_BUCKET=
|
|
S3_REGION=us-west-2
|
|
AWS_ACCESS_KEY_ID=
|
|
AWS_SECRET_ACCESS_KEY=
|
|
# AWS_ENDPOINT_URL — optional S3-compatible endpoint (MinIO, RustFS, R2, etc.).
|
|
# For internal Docker/VPC hosts such as http://rustfs:9000, leave
|
|
# ATTACHMENT_DOWNLOAD_MODE=auto or set proxy explicitly so browsers/CLI do
|
|
# not need direct access to the object store.
|
|
AWS_ENDPOINT_URL=
|
|
ATTACHMENT_DOWNLOAD_MODE=auto
|
|
ATTACHMENT_DOWNLOAD_URL_TTL=30m
|
|
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=
|
|
|
|
# AUTH_TOKEN_TTL — auth token lifetime. Accepts Go duration strings (e.g.
|
|
# "8760h", "720h30m") or plain integer seconds.
|
|
# Default: 2592000 (30 days). Self-hosted deployments on trusted networks can
|
|
# set a longer value to reduce re-authentication frequency.
|
|
# Note: longer TTL = longer exposure window if a cookie is leaked.
|
|
# AUTH_TOKEN_TTL=2592000
|
|
|
|
# Local file storage (fallback when S3_BUCKET is not set)
|
|
LOCAL_UPLOAD_DIR=./data/uploads
|
|
# Derived by Makefile / local scripts from the backend port.
|
|
# Set explicitly only when uploads are served through a different public URL.
|
|
# 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: CORS_ALLOWED_ORIGINS=https://app.multica.ai,https://staging.multica.ai
|
|
CORS_ALLOWED_ORIGINS=
|
|
|
|
# ==================== Rate limiting (optional Redis) ====================
|
|
# Per-IP fixed-window rate limiter on the public auth endpoints
|
|
# (/auth/send-code, /auth/verify-code, /auth/google). Backed by Redis.
|
|
# When REDIS_URL is unset the limiter is a no-op (fail-open) and the
|
|
# backend logs "rate limiting disabled: REDIS_URL not configured" at
|
|
# startup. The same REDIS_URL is reused by the realtime fan-out hub,
|
|
# the PAT cache, and the daemon-token cache.
|
|
# REDIS_URL=redis://localhost:6379/0
|
|
# Max requests per IP per minute. Defaults are 5 for send-code/google
|
|
# and 20 for verify-code.
|
|
# RATE_LIMIT_AUTH=5
|
|
# RATE_LIMIT_AUTH_VERIFY=20
|
|
# Comma-separated CIDRs whose X-Forwarded-For the auth limiter is
|
|
# allowed to trust. Empty (default) = never trust XFF, only RemoteAddr.
|
|
# REQUIRED behind a reverse proxy — otherwise every real user shares
|
|
# the proxy IP and the whole deployment lands in one bucket, turning
|
|
# /auth/send-code into 5 req/min site-wide. Use e.g. "127.0.0.1/32,::1/128"
|
|
# for same-host Caddy/Nginx, or the CDN's published ranges for ALB/CF.
|
|
# This is a separate list from MULTICA_TRUSTED_PROXIES above (which
|
|
# governs the autopilot webhook limiter).
|
|
# RATE_LIMIT_TRUSTED_PROXIES=
|
|
|
|
# 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 <token>`.
|
|
# REALTIME_METRICS_TOKEN=
|
|
|
|
# GitHub App integration (Settings → GitHub "Connect GitHub")
|
|
# Both must be set for the Connect button to enable and for webhooks to be
|
|
# accepted; leave empty to disable the integration. See docs/github-integration.
|
|
# GITHUB_APP_SLUG is the tail of https://github.com/apps/<slug>.
|
|
GITHUB_APP_SLUG=
|
|
GITHUB_WEBHOOK_SECRET=
|
|
# Optional: GitHub App identity for App-authenticated REST calls. When set,
|
|
# the setup callback enriches the installation row with the real account
|
|
# login (org / user name) immediately after install. When unset, the row
|
|
# is created with the "unknown" placeholder and the next `installation`
|
|
# webhook from GitHub overwrites it — set both to skip that interim flash.
|
|
# GITHUB_APP_ID is the numeric "App ID" shown on the App's settings page.
|
|
# GITHUB_APP_PRIVATE_KEY is the full PEM block (including BEGIN/END lines)
|
|
# generated under "Private keys" on that same page; preserve newlines.
|
|
GITHUB_APP_ID=
|
|
GITHUB_APP_PRIVATE_KEY=
|
|
|
|
# Lark / Feishu bot integration (Settings → Integrations "Bind to Lark")
|
|
# Off until MULTICA_LARK_SECRET_KEY is set — a base64-encoded 32-byte key
|
|
# that encrypts each Bot's app secret at rest. Leave empty to disable.
|
|
# Generate one with: openssl rand -base64 32
|
|
MULTICA_LARK_SECRET_KEY=
|
|
# Mainland 飞书 and international Lark are auto-detected per installation
|
|
# (at QR scan) and served side by side — LEAVE THESE EMPTY for normal use.
|
|
# They are optional deployment-wide overrides that force EVERY installation
|
|
# onto one host (a proxy, a mock for tests, or a single-cloud staging
|
|
# setup); HTTP drives outbound Open Platform API calls, CALLBACK the inbound
|
|
# long-conn bootstrap. NOTE: if you previously ran international Lark by
|
|
# setting these to https://open.larksuite.com, the server relabels your
|
|
# existing installs to region=lark on first boot after upgrade, so you can
|
|
# clear these afterwards. See docs/lark-bot-integration.
|
|
MULTICA_LARK_HTTP_BASE_URL=
|
|
MULTICA_LARK_CALLBACK_BASE_URL=
|
|
|
|
# Frontend
|
|
# Leave empty — auto-derived from page origin in browser, set by Makefile for local dev.
|
|
# NEXT_PUBLIC_API_URL also feeds the Next.js SSR proxy when explicitly set.
|
|
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=
|
|
|
|
# Set to "true" to disable workspace creation for every caller on this
|
|
# instance (#3433). Operators usually leave this unset, bootstrap the
|
|
# shared workspace, then flip this to "true" and restart so subsequent
|
|
# users join only via invitations and the entire deployment is visible to
|
|
# the platform admin. The web UI reads this from /api/config at runtime,
|
|
# so toggling requires a backend restart but not a frontend rebuild.
|
|
DISABLE_WORKSPACE_CREATION=
|
|
|
|
# ==================== 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
|
|
# Optional override for the `environment` PostHog event property.
|
|
# Defaults from APP_ENV and normalizes to production / staging / dev.
|
|
ANALYTICS_ENVIRONMENT=
|
|
# Force the no-op client even when POSTHOG_API_KEY is set (CI / opt-out).
|
|
ANALYTICS_DISABLED=
|