Environment variables

Every deployment variable for Lunnoa Automate, what it controls, and whether it is required.

Use this page when you self-host Lunnoa Automate and need to know which variable steers what. Values live in a single .env file at the repository root for Docker Compose and local pnpm runs, or in your orchestrator's secret store for production.

Where variables are defined

ArtifactRole
.env.exampleLocal and UAT template with comments
.env.prod.exampleProduction template (SigNoz, OpenConnector, compose overrides)
docker-compose*.ymlInjects service URLs (DATABASE_URL, REDIS_HOST, S3_ENDPOINT, WEAVIATE_URL, DOCLING_URL, OPEN_CONNECTOR_BASE_URL, …) inside Docker networks

Generate a starter .env with random secrets:

setup-env.sh
./scripts/setup-env.sh

Put server and sidecar secrets in that one .env (or secret store). UI VITE_* values are set at image build time, not in the server runtime env. For email, object storage, OAuth apps, SSO, and OpenTelemetry export, prefer Admin Space when a database config exists; it overrides matching env vars.

Required server variables

The server refuses to start without these. CRYPTO_ENCRYPTION_KEY must be exactly 32 characters. FEATHERLESS_API_KEY must be non-empty.

VariableControlsExample
ENVIRONMENTdevelopment or production. Affects OAuth callbacks, S3 paths, knowledge namespaces, email behaviourproduction
DATABASE_URLPostgreSQL connection string (Prisma)postgresql://user:pass@host:5432/lunnoa?schema=public
SERVER_URLPublic API base URL (OAuth callbacks, webhooks)https://automate.example.com
CLIENT_URLUI origin (CORS, links in emails)https://automate.example.com
PORTHTTP listen port inside the server container9094
AUTH_JWT_SECRETSigns session JWTslong random string
APP_OAUTH_CALLBACK_STATE_SECRETEncrypts OAuth state parameterslong random string
CRYPTO_ENCRYPTION_KEYEncrypts stored connection secrets (32 chars)32-character key
FEATHERLESS_API_KEYBootstraps default Lunnoa LLMs connection; new agents default to DeepSeek on this providerAPI key from Featherless

Core platform (optional)

VariableRequiredDefaultWhat it steers
PLATFORM_NAMENoLunnoa AutomateWhite-label name in the UI
CORS_ALLOWED_ORIGINSNoComma-separated extra browser origins for custom portals (Pattern B in the Public API). CLIENT_URL is always allowed
API_KEYS_ENABLEDNotrueMaster switch for lna_ machine API keys. Set false to reject all API keys
AUTH_DISABLED_METHODSNoComma-separated: password, google. SuperAdmins can always use password (break-glass)
NGROK_TUNNEL_URLNoLocal dev tunnel for OAuth and webhooks when ENVIRONMENT=development
NEW_USER_WORKFLOW_IDNoWorkflow (with webhook trigger) to run after signup
CRON_TRIGGER_POLLING_INTERVALNo5 min cronHow often polling triggers are checked
DEV_EMAIL_DOMAINNo@lunnoalabs.chDev-only email domain for test endpoints

Database and Redis

VariableRequiredDefaultWhat it steers
POSTGRES_DBCompose / setup scriptlunnoaDatabase name (compose builds DATABASE_URL)
POSTGRES_USERCompose / setup scriptDatabase user
POSTGRES_PASSWORDCompose / setup scriptDatabase password
POSTGRES_HOSTLocal pnpm onlylocalhostHost for setup-env script
POSTGRES_PORTLocal pnpm only5435Host port mapped to Postgres
REDIS_HOSTNolocalhostBullMQ job queue (workflows, agent turns)
REDIS_PORTNo6379Redis port
REDIS_PASSWORDNoRedis auth (set in prod compose)
REDIS_TLS_ENABLEDNofalseTLS for Redis connections

Redis is required for parallel workflow execution and resumable agent chat streams.

Object storage (S3-compatible)

Used for profile images, workspace logos, knowledge uploads, and temporary workflow files. Super Admin → Object Storage overrides these when an active verified config exists.

VariableRequiredDefaultWhat it steers
S3_ACCESS_KEY_IDNo*S3 access key (*optional on AWS ECS with IAM role)
S3_SECRET_ACCESS_KEYNo*S3 secret key
S3_REGIONFor KnowledgeAWS region
S3_BUCKET_IDFor KnowledgeBucket name
S3_ENDPOINTNoAWS defaultCustom endpoint (MinIO, R2, …). Compose sets http://minio:9000
S3_FORCE_PATH_STYLENofalseSet true for MinIO and many S3-compatible stores
S3_PUBLIC_BASE_URLNoPublic CDN or custom domain prefix for readable uploads
MINIO_ROOT_USERCompose onlyminioadminMinIO admin user (maps to S3_ACCESS_KEY_ID in compose)
MINIO_ROOT_PASSWORDCompose onlyminioadminMinIO admin password

GCP_STORAGE_* env vars are no longer read by the server. Configure Google Cloud Storage in Admin Space instead.

Knowledge (vector store)

Knowledge needs storage (S3 env or Admin Space storage) and Weaviate.

VariableRequiredDefaultWhat it steers
WEAVIATE_URLFor KnowledgeWeaviate HTTP endpoint. Compose: http://weaviate:8080
WEAVIATE_GRPC_URLFor KnowledgegRPC host:port (no scheme). Compose: weaviate:50051
WEAVIATE_API_KEYNoAuth when anonymous access is disabled
WEAVIATE_COLLECTION_NAMENoKnowledgeDeprecated. Each notebook gets its own collection

Legacy Pinecone (PINECONE_API_KEY, PINECONE_INDEX_NAME) is retained in config but Weaviate is the supported path.

AI providers

VariableRequiredDefaultWhat it steers
FEATHERLESS_API_KEYYesDefault platform LLM connection at boot
OPENAI_API_KEYNoOpenAI actions and embeddings when configured
ANTHROPIC_API_KEYNoAnthropic models
GEMINI_API_KEYNoGoogle Gemini models
OLLAMA_BASE_URLNohttp://127.0.0.1:11434/apiLocal Ollama endpoint
DEFAULT_LLM_PROVIDERNoopenaiFallback provider label for AI actions
DEFAULT_LLM_MODELNogpt-4oFallback model name
DEFAULT_EMBEDDING_PROVIDERNoopenaiEmbedding provider for legacy paths
DEFAULT_EMBEDDING_MODELNotext-embedding-3-smallEmbedding model name

Workspace admins can add more AI connections in the UI. FEATHERLESS_API_KEY is still mandatory at boot to provision the global default.

Document parsing (Docling)

VariableRequiredDefaultWhat it steers
DOCLING_URLNoDocling serve base URL. Compose sets http://docling:5001. Empty disables the Document Parser
DOCLING_API_KEYNoX-Api-Key header when Docling auth is enabled

Long-tail integrations

First-party apps are always on. These variables are optional. They add Pipedream and/or OpenConnector catalogues for MCP, workflow actions, and triggers. If a provider is unset or credentials are incomplete, the server logs a warning and treats that surface as none. The rest of the platform keeps running.

Provider switches

VariableRequiredDefaultWhat it steers
LUNNOA_MCP_PROVIDERNopipedream if Pipedream creds exist, else noneMCP catalogue: none, pipedream, open_connector
LUNNOA_ACTION_PROVIDERNononeWorkflow action catalogue: none, pipedream, open_connector
LUNNOA_TRIGGER_PROVIDERNononeWorkflow triggers (pipedream or none only; OpenConnector has no triggers)

Pipedream (cloud)

VariableRequiredDefaultWhat it steers
PIPEDREAM_CLIENT_IDWhen provider is pipedreamPipedream Connect OAuth client
PIPEDREAM_CLIENT_SECRETWhen provider is pipedreamPipedream Connect secret
PIPEDREAM_PROJECT_IDWhen provider is pipedreamPipedream project ID
PIPEDREAM_ENVIRONMENTNodevelopmentPipedream environment slug

OpenConnector (self-hosted sidecar)

OpenConnector is included in docker-compose.local.yml, docker-compose.yml, docker-compose.uat.yml, and docker-compose.prod.yml. It does not replace other sidecars (Postgres, Redis, MinIO, Weaviate, Docling, SigNoz). Only the Lunnoa server talks to it.

Put these in the same .env as the server. Compose maps OPEN_CONNECTOR_* into the server and into the open-connector container as OOMOL_CONNECT_*.

VariableRequiredDefaultWhat it steers
OPEN_CONNECTOR_BASE_URLWhen provider is open_connectorCompose: http://open-connector:3000Sidecar origin for the Lunnoa server. On the Docker network you usually omit this from .env; compose injects the default. Override only if OC runs elsewhere
OPEN_CONNECTOR_RUNTIME_TOKENWhen provider is open_connectorBearer token for MCP and action runtime calls (oct_… or a bootstrap secret). You generate it (see below)
OPEN_CONNECTOR_ADMIN_TOKENFor catalog sync / admin APIProtects OC admin API and console. You invent a strong secret and set it before start
OOMOL_CONNECT_ENCRYPTION_KEYOpenConnector containerAES-256-GCM key for credentials stored by OC. Sidecar only; Lunnoa does not read this key. Generate a long random secret and keep it stable

Example for UAT or production when you enable OpenConnector:

bash
LUNNOA_MCP_PROVIDER=open_connector
LUNNOA_ACTION_PROVIDER=open_connector
LUNNOA_TRIGGER_PROVIDER=none
# OPEN_CONNECTOR_BASE_URL optional when using compose (defaults to http://open-connector:3000)
OPEN_CONNECTOR_RUNTIME_TOKEN=
OPEN_CONNECTOR_ADMIN_TOKEN=
OOMOL_CONNECT_ENCRYPTION_KEY=

Local debug console (local compose only): http://localhost:3100. UAT and prod keep OC on the internal Docker network only.

Web search, scraping, and voice

VariableRequiredWhat it steers
SERPER_API_KEYNoGoogle search for agents and workflows (WEB_SEARCH feature flag)
APIFY_API_KEYNoWebsite extraction (Apify)
APIFY_EXTRACT_DYNAMIC_CONTENT_TASK_IDNoApify task for dynamic pages (WEB_EXTRACTION_DYNAMIC)
APIFY_EXTRACT_STATIC_CONTENT_TASK_IDNoApify task for static pages (WEB_EXTRACTION_STATIC)
VAPI_API_KEYNoAI phone calls (CALLING feature flag)

Runtime app installation

VariableRequiredDefaultWhat it steers
PLUGINS_DIRNo/data/pluginsWritable directory for npm-installed integration apps
APP_REGISTRY_ALLOWLISTNoemptyComma-separated registry URLs or scopes (@lunnoa/*). Empty disables runtime install
APP_REGISTRY_TOKENNonpm _authToken for private registries

Jobs dashboard (SuperAdmin)

VariableRequiredDefaultWhat it steers
JOBS_DASHBOARD_ENABLEDNotrueBullMQ UI at /api/admin/jobs
JOBS_DASHBOARD_ALLOW_MUTATIONSNofalseRetry, promote, remove buttons
JOBS_DASHBOARD_REDACT_PAYLOADSNotrueMask secrets in job payloads
JOBS_DASHBOARD_SHOW_AGENT_PROMPTSNofalseShow full agent message content (staging only)

HTTP and agent worker tuning

VariableRequiredDefaultWhat it steers
SERVER_REQUEST_TIMEOUT_MSNo1200000Max HTTP request duration (20 min)
KEEP_ALIVE_TIMEOUT_MSNo1210000Node keep-alive timeout
HEADERS_TIMEOUT_MSNo1215000Node headers timeout
AGENT_WORKER_CONCURRENCYNo10Parallel agent turn workers
AGENT_TURN_MAX_MSNo600000Max duration per agent turn
AGENT_TOOL_OUTPUT_MAX_CHARSNobuilt-in limitTruncate tool output sent back to the model
TASK_RUN_STREAM_ATTACH_TIMEOUT_MSNo60000Timeout attaching to a running stream
CHAT_RESUMABLE_STREAMSNoenabledSet false to disable Redis-backed stream resume
CHAT_STREAM_CHUNK_DEBUGNooffVerbose SSE chunk logging
CHAT_STREAM_CHUNK_DEBUG_VERBOSENooffExtra verbose chunk logging
DEBUG_LOG_SYSTEM_PROMPTNooffLog agent system prompts (never in prod)

AWS Parameter Store (cloud deployments)

VariableRequiredWhat it steers
PARAM_STORE_ACCESS_KEYWhen using SSMAWS access key
PARAM_STORE_SECRET_ACCESS_KEYWhen using SSMAWS secret key
PARAM_STORE_REGIONWhen using SSMAWS region

When all three are set, the server loads /{ENVIRONMENT}/server-core/* from Parameter Store. Local .env still supplies keys missing from SSM (typical for dev integration secrets).

UI build-time variables (VITE_*)

Set these when building the UI image or running pnpm locally. They are not read by the server.

VariableRequiredDefaultWhat it steers
VITE_CLIENT_URLLocal devhttp://localhost:5173Where the browser thinks the UI lives
VITE_SERVER_URLLocal devhttp://localhost:9094API origin for fetch and SSE. Leave empty in prod when nginx proxies /api same-origin
VITE_ENABLE_ANALYTICSNooffVercel Analytics in the UI bundle
VITE_ENABLE_BROWSER_OTELNooffBrowser OpenTelemetry traces
VITE_OTEL_EXPORTER_OTLP_ENDPOINTWhen browser OTEL on/otlp in devOTLP HTTP endpoint for UI traces
VITE_OTEL_SERVICE_NAMENolunnoa-automate-uiService name in traces
VITE_MOCK_API_CALLSNooffMock API layer (local dev only)
VITE_LOG_API_CALLSNooffConsole-log API calls (local dev only)

Production UI images are built in CI with PROD_CLIENT_URL and PROD_SERVER_URL GitHub repository variables (see .github/workflows/deploy-ui-container.yml), not from the server .env.

Observability stack (SigNoz compose only)

VariableRequiredWhat it steers
SIGNOZ_JWT_SECRETProd/UAT SigNoz stackSigNoz UI authentication

Server-side trace export is configured in Admin Space → Observability, not via OTEL_* env vars on the server.

Configure in Admin Space instead of env

These capabilities do not need (or no longer accept) deployment env vars:

CapabilityWhere to configure
Email (SMTP, Gmail, SendGrid, …)Admin Space → System Settings → Email
Object storage (S3, R2, GCS)Super Admin → Object Storage
OAuth apps (Google, Microsoft, HubSpot, …)Admin Space → App configuration
SSO (OIDC) and SCIMAdmin Space → SSO
OpenTelemetry exportAdmin Space → Observability
AI provider connections (beyond boot default)Admin Space → AI configuration

MAIL_* and SKIP_EMAIL_VERIFICATION env vars are ignored if present.

Feature flags vs variables

On startup the discovery service logs which features are enabled. Common env-driven gates:

FeatureEnv dependency
KNOWLEDGEWEAVIATE_URL + (S3_REGION + S3_BUCKET_ID or Admin storage)
WEB_SEARCHSERPER_API_KEY
WEB_EXTRACTION_DYNAMICAPIFY_API_KEY + APIFY_EXTRACT_DYNAMIC_CONTENT_TASK_ID
WEB_EXTRACTION_STATICAPIFY_API_KEY + APIFY_EXTRACT_STATIC_CONTENT_TASK_ID
CALLINGVAPI_API_KEY
EMAILSAdmin Space email config (database)
SSO / SCIMAdmin Space providers and tokens (database)

Workflows, agents, connections, variables, teams, skills, and code execution are on by default.

Quick reference by deployment path

  1. Local pnpm

    Copy .env.example.env, run setup-env, set FEATHERLESS_API_KEY, start Postgres/Redis/MinIO/Weaviate via compose profiles as needed.

  2. Docker Compose (UAT/prod)

    Copy .env.prod.example.env, fill secrets (including OpenConnector tokens if you enable long-tail OC), run docker compose -f docker-compose.prod.yml up -d. Compose injects internal service URLs such as OPEN_CONNECTOR_BASE_URL.

  3. Dokploy / Kubernetes

    Map the required server variables plus Redis, S3, and Weaviate for full platform features. Build or pull a UI image with correct VITE_* build args.