molecule-core/.env.example
Hongming Wang 34fb3fd471 feat(provisioner): configurable per-tier memory/CPU limits (#14)
Resolves #14. ApplyTierConfig now reads TIER{2,3,4}_MEMORY_MB and
TIER{2,3,4}_CPU_SHARES env vars, falling back to the compiled defaults
agreed in the issue:

  - T2: 512 MiB  / 1024 shares (1 CPU)  — unchanged baseline
  - T3: 2048 MiB / 2048 shares (2 CPU)  — new cap (previously uncapped)
  - T4: 4096 MiB / 4096 shares (4 CPU)  — new cap (previously uncapped)

CPU_SHARES follows Docker's 1024 = 1 CPU convention; internally the
value is translated to NanoCPUs for a hard allocation so behaviour
remains deterministic across hosts. Malformed or non-positive env
values silently fall back to the default.

Behaviour change note: T3 and T4 previously had no explicit cap.
Operators who relied on unlimited can set very large TIERn_MEMORY_MB /
TIERn_CPU_SHARES values; a follow-up can add unset-means-unlimited
semantics if required.

Tests:
  - TestGetTierMemoryMB_DefaultsMatchLegacy
  - TestGetTierMemoryMB_EnvOverride (covers malformed + zero fallback)
  - TestGetTierCPUShares_EnvOverride
  - TestApplyTierConfig_T3_UsesEnvOverride (wiring)
  - TestApplyTierConfig_T3_DefaultCap (documents the new cap)

Docs: .env.example section + CLAUDE.md platform env-vars list updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:49:37 -07:00

107 lines
7.3 KiB
Plaintext

# Postgres
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=molecule
DATABASE_URL=postgres://USER:PASS@postgres:5432/molecule?sslmode=disable
# Redis
REDIS_URL=redis://redis:6379
# Platform
PORT=8080
SECRETS_ENCRYPTION_KEY= # 32-byte key (raw or base64). Leave empty for plaintext (dev only).
CONFIGS_DIR= # Path to workspace-configs-templates/ (auto-discovered if empty)
PLUGINS_DIR= # Path to plugins/ directory (default: /plugins in container)
# PLATFORM_URL=http://host.docker.internal:8080 # URL agent containers use to reach the platform; injected into workspace env. Default derives from PORT.
# MOLECULE_URL=http://localhost:8080 # Canonical MCP-client URL (mirrors PLATFORM_URL inside containers). Read by the MCP server (mcp-server/) and Molecule MCP tooling.
# WORKSPACE_DIR= # Optional global host path bind-mounted to /workspace in every container. Per-workspace workspace_dir column overrides this; if neither is set each workspace gets an isolated Docker named volume.
# MOLECULE_ENV=development # Environment label (development/staging/production). Used for log tagging and conditional behaviour.
# MOLECULE_ENABLE_TEST_TOKENS= # Set to 1 to expose GET /admin/workspaces/:id/test-token (mints a fresh bearer token for E2E scripts). The route is auto-enabled when MOLECULE_ENV != production; this flag is the explicit override. Leave unset/0 in prod — the route 404s unless enabled.
# CORS / rate limiting
# CORS_ORIGINS=http://localhost:3000,http://localhost:3001 # Comma-separated allowed origins for the HTTP API.
# RATE_LIMIT=600 # Requests/minute per client (default 600).
# Activity retention
# ACTIVITY_RETENTION_DAYS=7 # Days to keep rows in activity_logs before pruning.
# ACTIVITY_CLEANUP_INTERVAL_HOURS=6 # How often the background pruner runs.
# Container/runtime detection
# MOLECULE_IN_DOCKER= # Set when running the platform inside Docker (accepts 1/0, true/false). Triggers A2A proxy to rewrite 127.0.0.1:<port> agent URLs to Docker bridge hostnames. Auto-detected via /.dockerenv; only set if detection fails or to force off.
# Observability (Awareness)
# AWARENESS_URL= # If set, injected into workspace containers along with a deterministic AWARENESS_NAMESPACE derived from workspace ID. Enables the cross-session memory MCP server.
# GitHub
# GITHUB_REPO=owner/repo # Target repo for agent initial_prompt clone (e.g. Molecule-AI/molecule-monorepo). Read inside workspace containers.
# GITHUB_TOKEN= # Personal access token / installation token used by agents that clone private repos. Register as a global secret via POST /admin/secrets for propagation to workspace env. Token is used in-URL during clone and then scrubbed from .git/config via `git remote set-url`.
# Webhooks
# GITHUB_WEBHOOK_SECRET= # HMAC secret used to verify incoming GitHub webhook payloads at /webhooks/github.
# CLI clients
# MOLECLI_URL=http://localhost:8080 # URL the molecli TUI uses to reach the platform.
# Plugin install safeguards (POST /workspaces/:id/plugins)
# All three bound the cost of a single install so a slow/malicious
# source can't tie up a handler. Defaults are sane for typical use.
PLUGIN_INSTALL_BODY_MAX_BYTES=65536 # max request body size (default: 64 KiB)
PLUGIN_INSTALL_FETCH_TIMEOUT=5m # duration string; whole fetch+copy deadline
PLUGIN_INSTALL_MAX_DIR_BYTES=104857600 # max staged-tree size (default: 100 MiB)
# Phase 30.7 — remote-agent liveness threshold. Workspaces with
# runtime='external' are marked offline if their last_heartbeat_at is
# older than this many seconds. Slightly larger than the 60s Redis TTL
# so transient WAN hiccups don't flap online/offline. Set to 0 to use
# the built-in default (90s).
REMOTE_LIVENESS_STALE_AFTER=90
# Canvas
NEXT_PUBLIC_PLATFORM_URL=http://localhost:8080
NEXT_PUBLIC_WS_URL=ws://localhost:8080/ws
# Workspace Runtime
ANTHROPIC_API_KEY=
OPENROUTER_API_KEY= # OpenRouter API key (openrouter.ai). Use with model: openrouter:anthropic/claude-3.5-haiku. Also acts as the fallback key for the hermes runtime when HERMES_API_KEY is unset.
HERMES_API_KEY= # Nous Research Portal API key (inference-prod.nousresearch.com). Used by the hermes runtime; falls back to OPENROUTER_API_KEY if unset.
GROQ_API_KEY= # Groq API key (console.groq.com). Use with model: groq:llama-3.3-70b-versatile
CEREBRAS_API_KEY= # Cerebras API key (cloud.cerebras.ai). Use with model: cerebras:llama3.1-8b
GOOGLE_API_KEY= # Google AI API key (aistudio.google.com). Use with model: google_genai:gemini-2.5-flash
MAX_TOKENS=2048 # Max output tokens for OpenRouter requests (default: 2048)
LANGGRAPH_RECURSION_LIMIT=500 # LangGraph/DeepAgents max ReAct steps per turn (lib default: 25; raised to 500 — PM fan-out to 6+ reports + synthesis routinely exceeds 100)
MODEL_PROVIDER=anthropic:claude-sonnet-4-6 # Format: provider:model. Providers: anthropic, openai, openrouter, groq, cerebras, google_genai, ollama
# ---- Workspace tier resource limits (issue #14) ----
# Per-tier memory/CPU caps applied to each workspace Docker container.
# CPU_SHARES follows the Docker convention: 1024 shares == 1 CPU.
# Any value <=0 or malformed falls back to the compiled default shown.
# Tier 1 is sandboxed (tmpfs, readonly) and is not resource-capped here.
TIER2_MEMORY_MB=512 # Standard tier memory cap (default 512 MiB)
TIER2_CPU_SHARES=1024 # Standard tier CPU (default 1024 = 1 CPU)
TIER3_MEMORY_MB=2048 # Privileged tier memory cap (default 2048 MiB; previously uncapped)
TIER3_CPU_SHARES=2048 # Privileged tier CPU (default 2048 = 2 CPU; previously uncapped)
TIER4_MEMORY_MB=4096 # Full-host tier memory cap (default 4096 MiB; previously uncapped)
TIER4_CPU_SHARES=4096 # Full-host tier CPU (default 4096 = 4 CPU; previously uncapped)
# Social Channels (optional — configure per-workspace via API or Canvas)
TELEGRAM_BOT_TOKEN= # Telegram Bot API token (talk to @BotFather). Used as default for new Telegram channels.
# Langfuse (optional observability)
LANGFUSE_HOST=http://langfuse-web:3000
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
# ---- Operator identity (for org-templates/reno-stars/, see OPERATOR_NOTES.md) ----
# These are NOT consumed by the platform itself — they're documented here so
# operators of the reno-stars template (and any future operator-personalised
# template) know what to set as global_secrets. The platform injects every
# global_secret into every workspace container as an env var; the agent
# system-prompts reference them via ${VAR_NAME}.
OPERATOR_EMAIL= # e.g. you@example.com
OPERATOR_PHONE= # e.g. 555-123-4567 (display only, not used for SMS)
OPERATOR_TELEGRAM_ID= # numeric Telegram user ID (for bot DMs)
GADS_MCC_ID= # Google Ads MCC (manager) account ID, format 123-456-7890
GADS_CUSTOMER_ID= # Google Ads child customer ID, format 987-654-3210
GCP_PROJECT_ID= # Google Cloud project ID (e.g. my-website-123456)
GSC_SERVICE_ACCOUNT= # Search Console reporter service account email