Skip to content
Reference

Environment Variables

Look up Nexia local, test, production, and Cloudflare environment ownership without copying values across runtime boundaries.

Environment Variables

This reference is for Nexia maintainers who already have authorized access to the private host environment. Core is not distributed to external developers. These host commands are not prerequisites for the public CLI and cloud sandbox; start with the quickstart.

Find the receiving runtime and capability before copying a value. For ordinary App work, use Set up App development; enable optional services only through their focused guide. The inventory below is for configuring Core and its services, not for declaring App business settings.

Find a setting

Three files publish different views of that contract. They are not interchangeable.

FileAuthorityHow it is used
.env.exampleLocal Docker Composetask setup copies it to ignored .env; Compose injects selected values into each service
.env.testing.exampleAutomated PHP testsTest bootstrap reads it as a safety fixture; use a unique database and tenant prefix per worktree
deploy/production/.env.exampleProduction owner catalogRegister each value only with the owner named by its section; no process loads this file wholesale

The production catalog includes copies of Laravel Cloud-managed framework values only because scripts/validate-prod-env.sh validates a file. Do not manually register a value labeled Managed. A blank value means “supply this secret or endpoint when its capability is enabled,” not an empty production credential.

This page is exhaustive for Nexia's supported operator contract: every assignment in the three catalogs, every supported source-level override intentionally left out of them, and every compatibility or container-internal name that is easy to mistake for an operator setting. Laravel and installed packages expose additional upstream env() hooks; those are not Nexia-supported deployment inputs unless they appear here.

Minimal example

After Set up App development, inspect the active profile without printing credentials:

Code example
Shell
rg '^(APP_ENV|DB_DATABASE|SCOUT_DRIVER)=' .env

The first run creates .env and .env.testing, starts the core profile, migrates and seeds the databases, and leaves AGENT_SERVICE_TOKEN blank because the Agent profile is optional. Enable that runtime separately through Enable the Agent Gateway. For isolated analysis configuration, see How Agent requests run.

When multiple worktrees run tests, change both isolation values in each worktree's .env.testing:

DB_DATABASE=nexia_test_agent_sse
TEST_TENANCY_DB_PREFIX=test_nexia_agent_sse_

Parameters

Scope and legend

The tables group the assignments published by the local, test, and production catalogs. blank means the file contains the key with no value. — means that file does not assign it. Classifications are per receiving runtime: Required must exist for that runtime, Conditional is required only when the named capability is enabled, Optional keeps the stated default or disables the feature, and Managed is supplied by the platform or tracked configuration.

Framework and process runtime

VariableReceiverClassSecretLocalTestProductionEffect
APP_NAMELaravelRequiredNoNexiaNexiaNexia-Cloud-OSApplication display name and default mail sender name
APP_ENVLaravelManagedNolocaltestingproductionSelects environment-specific safety behavior
APP_KEYLaravelRequired; managed in productionYesblankblankbase64:CHANGE_MERoot key for Laravel application encryption and encrypted framework payloads
APP_DEBUGLaravelManagedNotruetruefalseControls exception detail; production must stay false
APP_URLLaravelManagedNohttp://localhosthttp://localhosthttps://nexia.toCanonical application URL and Agent JWT issuer
APP_LOCALELaravelOptionalNoenkoenDefault locale
APP_FALLBACK_LOCALELaravelOptionalNoenenenTranslation fallback locale
APP_FAKER_LOCALELaravelOptionalNoko_KRko_KRko_KRSeeder and factory locale
APP_MAINTENANCE_DRIVERLaravelOptionalNofilefilefileMaintenance-mode storage
BCRYPT_ROUNDSLaravelOptionalNo12412Password hash work factor
LOG_CHANNELLaravelOptionalNostacknullstackDefault log channel
LOG_STACKLaravelOptionalNosingle—singleChannels included by the stack logger
LOG_DEPRECATIONS_CHANNELLaravelOptionalNonull—nullDeprecation log destination
LOG_LEVELLaravelOptionalNodebugdebuginfoMinimum Laravel log severity; Gateway uses AGENT_GATEWAY_LOG_LEVEL
OCTANE_SERVERLaravelOptionalNofrankenphp——Octane server implementation
OCTANE_WORKERSComposeOptionalNo1——Local Octane worker count
OCTANE_MAX_REQUESTSComposeOptionalNo500——Requests handled before local worker recycling
OCTANE_MAX_EXECUTION_TIMELaravelOptionalNo600——Maximum Octane task execution time in seconds

Data, sessions, storage, and delivery

VariableReceiverClassSecretLocalTestProductionEffect
DB_CONNECTIONLaravelManagedNopgsqlpgsqlmanagedDatabase driver
DB_HOSTLaravelManagedNopostgrespostgresmanagedDatabase host
DB_PORTLaravelManagedNo54325432managedDatabase port
DB_DATABASELaravelManagedNonexianexia_testmanagedCentral database name
DB_USERNAMELaravelManagedNopostgrespostgresmanagedDatabase login name
DB_PASSWORDLaravel, Langfuse ComposeRequired; managed by attached production DBYessecretsecretblankDatabase credential; self-hosted Langfuse also derives its DSN from it
TEST_TENANCY_DB_PREFIXTest bootstrapRequired in testsNo—test_nexia_—Prefix of disposable parallel tenant databases; unique per worktree
REDIS_CLIENTLaravelManagedNophpredisphpredismanagedRedis client implementation
REDIS_HOSTLaravelManagedNoredisredismanagedRedis host
REDIS_PASSWORDLaravelManagedYesnullnullmanagedRedis credential
REDIS_PORTLaravelManagedNo63796379managedRedis port
SESSION_DRIVERLaravelManagedNoredisarraymanagedSession persistence; tests keep it in memory
SESSION_STORELaravelRequired in productionNosession—sessionKeeps sessions in the dedicated, non-tenant-prefixed Redis store
SESSION_LIFETIMELaravelOptionalNo120—120Idle session lifetime in minutes
SESSION_ENCRYPTLaravelOptionalNofalse——Encrypts serialized session payloads
SESSION_PATHLaravelOptionalNo/——Session cookie path
SESSION_DOMAINLaravelOptionalNonull——Session cookie domain
CACHE_STORELaravelManagedNoredisfilemanagedDefault application cache; Agent uses explicit stores for some contracts
QUEUE_CONNECTIONLaravelManagedNoredissyncmanagedQueue backend; tests execute synchronously
FILESYSTEM_DISKLaravelOptionalNolocallocallocalFramework default disk, distinct from product-storage ownership

Product storage, realtime, mail, billing, and frontend

VariableReceiverClassSecretLocalTestProductionEffect
PRODUCT_STORAGE_DRIVERLaravelRequiredNolocal—s3Selects ownership-aware local or S3-compatible product disks
AWS_ACCESS_KEY_IDLaravel storageConditionalYesblank—blankS3/R2 credential identifier
AWS_SECRET_ACCESS_KEYLaravel storageConditionalYesblank—blankS3/R2 secret credential
AWS_DEFAULT_REGIONLaravel storageConditionalNoauto—autoS3-compatible region
AWS_BUCKETLaravel storageConditionalNoblank—nexia-cloud-os-privatePrivate product bucket
AWS_PUBLIC_BUCKETLaravel storageConditionalNoblank—nexia-cloud-osPublic product bucket
AWS_URLLaravel storageConditionalNoblank—https://cdn.nexia.toPublic object URL base
AWS_ENDPOINTLaravel storageConditionalNoblank—R2 endpointS3-compatible API endpoint
AWS_USE_PATH_STYLE_ENDPOINTLaravel storageOptionalNofalse—falseSelects path-style instead of virtual-host requests
BROADCAST_CONNECTIONLaravel, local runtime-mode scriptOptional local; managed in productionNolognullreverbBroadcast transport; local reverb selection includes the reverb service in every runtime profile
REVERB_APP_IDLaravel, ReverbConditional local; managed in productionNoblank—blankReverb application identifier
REVERB_APP_KEYLaravel, Reverb, Vite, local runtime-mode scriptConditional local; managed in productionNoblank—blankReverb public application key; a nonblank local value includes the reverb service in every runtime profile
REVERB_APP_SECRETLaravel, ReverbConditional local; managed in productionYesblank—blankReverb signing secret
REVERB_HOSTLaravel, ViteConditional local; managed in productionNoreverb—reverbReverb host
REVERB_PORTLaravel, ViteConditional local; managed in productionNo6001—443Reverb port
REVERB_SCHEMELaravel, ViteConditional local; managed in productionNohttp—httpsReverb transport scheme
REVERB_SERVER_HOSTLaravelOptional local overrideNocommented——Backend-only Reverb host when the browser-facing host is unreachable from the app container
REVERB_SERVER_PORTLaravelOptional local overrideNocommented——Backend-only Reverb port; falls back to REVERB_PORT
REVERB_SERVER_SCHEMELaravelOptional local overrideNocommented——Backend-only Reverb scheme; falls back to REVERB_SCHEME
SANCTUM_STATEFUL_DOMAINSLaravel CloudRequiredNo——nexia.to,*.nexia.toBrowser origins treated as stateful Sanctum clients
MAIL_MAILERLaravelConditionalNosmtparraylogOutbound mail transport; production log sends nothing
MAIL_HOSTLaravelConditionalNomailpit—blankSMTP host
MAIL_PORTLaravelConditionalNo1025—587SMTP port
MAIL_USERNAMELaravelConditionalNonull—blankSMTP login name
MAIL_PASSWORDLaravelConditionalYesnull—blankSMTP credential
MAIL_SCHEMELaravelOptionalNonull—smtpExplicit SMTP URL scheme
MAIL_FROM_ADDRESSLaravelConditionalNonoreply@nexia.localhost—noreply@nexia.toDefault sender address
MAIL_FROM_NAMELaravelConditionalNo${APP_NAME}—${APP_NAME}Default sender name
STRIPE_KEYLaravelConditionalNoblank—blankPublishable billing key
STRIPE_SECRETLaravelConditionalYesblank—blankStripe API secret
VITE_PUBLIC_HOSTVite/browserRequired locallyNolocalhostlocalhost—Browser-visible local host used by frontend endpoints
VITE_REVERB_APP_KEYVite/browser, local runtime-mode scriptConditional local; managed in productionNo${REVERB_APP_KEY}—${REVERB_APP_KEY}Browser Reverb key; a nonblank local value includes the reverb service in every runtime profile
VITE_REVERB_HOSTVite/browserConditional local; managed in productionNo${VITE_PUBLIC_HOST}—${REVERB_HOST}Browser Reverb host
VITE_REVERB_PORTVite/browserConditional local; managed in productionNo——${REVERB_PORT}Browser Reverb port; local frontend config falls back to FORWARD_REVERB_PORT
VITE_REVERB_SCHEMEVite/browserConditional local; managed in productionNo${REVERB_SCHEME}—${REVERB_SCHEME}Browser Reverb scheme
VITE_USE_POLLINGViteOptionalNotruetrue—Enables filesystem polling for mounted local source
VITE_POLL_INTERVALViteOptionalNo3000——Local polling interval in milliseconds
VITE_SHOW_UI_SANDBOXVite/browserOptionalNofalse—falseExposes the development UI sandbox when true

For local task dev:up:* convergence, an explicitly exported process value is read before .env, including when it is empty; the script then applies the key's fallback (log for BROADCAST_CONNECTION, empty for the two app keys). Reverb is required when the resolved broadcast connection is reverb or either resolved app key is nonblank. The literal .env alias VITE_REVERB_APP_KEY=${REVERB_APP_KEY} resolves through REVERB_APP_KEY, so it does not enable Reverb when that source key is blank.

Local Docker ports and testing

These values belong to Docker Compose on the developer machine and never to Laravel Cloud or a container secret store.

VariableReceiverClassSecretLocalTestProductionEffect
FORWARD_WEB_BINDComposeOptionalNo127.0.0.1——Host interface for the application port
FORWARD_WEB_PORTComposeOptionalNo8080——Host application port
FORWARD_VITE_PORTComposeOptionalNo5173——Host Vite port
FORWARD_DB_PORTComposeOptionalNo54320——Host PostgreSQL port
FORWARD_REDIS_PORTComposeOptionalNo63790——Host Redis port
FORWARD_MAILPIT_PORTComposeOptionalNo8025——Host Mailpit UI port
FORWARD_MAILPIT_SMTP_PORTComposeOptionalNo1025——Host Mailpit SMTP port
FORWARD_REVERB_PORTComposeOptionalNo6001——Host Reverb port
FORWARD_TYPESENSE_PORTComposeOptionalNo8108——Host Typesense port

The test fixture also disables optional observation services so they cannot change test behavior:

VariableReceiverClassSecretLocalTestProductionEffect
PULSE_ENABLEDLaravel testsManaged test fixtureNo—false—Disables Pulse during tests
TELESCOPE_ENABLEDLaravel testsManaged test fixtureNo—false—Disables Telescope during tests
NIGHTWATCH_ENABLEDLaravel testsManaged test fixtureNo—false—Disables Nightwatch during tests
NEXIA_TEST_PROCESSESTest runnerOptionalNo—commented (8)—Caps parallel Pest workers; defaults to the container CPU count

Nexia identity, tenancy, files, and signatures

VariableReceiverClassSecretLocalTestProductionEffect
ADMIN_SEEDER_EMAILLaravel seederConditionalNoadmin@nexia.dev—blankFirst administrator identity
ADMIN_SEEDER_PASSWORDLaravel seederConditionalYespassword—blankFirst administrator password; rotate or remove after seeding
NEXIA_ADMIN_PATHLaravelOptionalNoadminadminadminCentral administration route prefix
NEXIA_OIDC_ID_TOKEN_LEEWAYLaravelOptionalNo60—60Accepted OIDC clock skew in seconds
TENANCY_DB_PREFIXLaravelOptionalNonexia_—nexia_Tenant database name prefix; changing it does not rename databases
TENANCY_PENDING_COUNTLaravelOptionalNo0—0Number of pre-warmed tenant databases; zero disables the pool
TENANCY_DOMAIN_RESOLVER_CACHELaravelOptionalNofalse—trueCaches tenant domain resolution
TENANCY_DOMAIN_RESOLVER_CACHE_TTLLaravelOptionalNo3600—3600Domain cache lifetime in seconds
MALWARE_SCANNERLaravelRequired for protected intakeNopassthrough—clamdSelects ClamD or an explicit local waiver
CLAMD_HOSTLaravelConditionalNoclamav—blankCanonical reachable ClamD host
CLAMD_PORTLaravelConditionalNo3310—3310Canonical ClamD TCP port
CLAMD_CONNECT_TIMEOUT_SECONDSLaravelOptionalNo2—2ClamD connect timeout
CLAMD_SCAN_TIMEOUT_SECONDSLaravelOptionalNo30—30ClamD scan timeout
SIGNATURE_PDF_PROCESSOR_EXPECTED_VERSIONLaravel healthOptionalNo8.71.2——Expected PDF processor package version
SIGNATURE_PDF_PROCESSOR_HEALTH_REQUIREDLaravel healthOptionalNofalse—code default trueMakes PDF runtime health a readiness requirement
NEXIA_SIGNATURE_DISPLAY_TIMEZONELaravelOptionalNoUTC—UTCDisplay timezone for signature evidence
APPROVAL_SESSION_EVIDENCE_FRESHNESS_MINUTESLaravelOptionalNo720—720Maximum age of session evidence used by Approval
SIGNATURE_ENABLEDLaravelOptionalNo——falseMaster production Signature rollout switch
SIGNATURE_TENANT_ALLOWLISTLaravelOptionalNo——blankNarrows Signature to listed tenants
SIGNATURE_LEGAL_ENTITY_ALLOWLISTLaravelOptionalNo——blankNarrows Signature to listed Legal Entities
SIGNATURE_PILOT_LEGAL_ENTITY_ALLOWLISTLaravelOptionalNo——blankNarrows the pilot cohort further
SIGNATURE_EXECUTION_ENGINELaravelOptionalNo——nativeSelects the Signature execution engine
SIGNATURE_BULK_REQUEST_ENABLEDLaravelOptionalNo——falseEnables bulk Signature requests
SIGNATURE_BULK_REQUEST_TENANT_ALLOWLISTLaravelOptionalNo——blankNarrows bulk requests to tenants
SIGNATURE_BULK_REQUEST_LEGAL_ENTITY_ALLOWLISTLaravelOptionalNo——blankNarrows bulk requests to Legal Entities
DOCUMENT_BINARY_MAX_FILE_KIBLaravelOptionalNo51200—51200Per-file upload limit
DOCUMENT_BINARY_MAX_ACTIVE_FILESLaravelOptionalNo20—20Maximum active files per owner
DOCUMENT_BINARY_MAX_TOTAL_KIBLaravelOptionalNo256000—256000Aggregate active-file limit
DOCUMENT_BINARY_MAX_EXTRACTED_CHARACTERSLaravelOptionalNo2000000—2000000Text extraction ceiling
DOCUMENT_BINARY_STAGE_TTL_HOURSLaravelOptionalNo48—48Unbound staged-file lifetime
DOCUMENT_BINARY_QUARANTINE_RETENTION_DAYSLaravelOptionalNo30—30Quarantined-file retention
DOCUMENT_BINARY_DEFAULT_BOUND_RETENTION_DAYSLaravelOptionalNo2555—2555Default bound-document retention
DOCUMENT_BINARY_EXTRACTION_TIMEOUT_SECONDSLaravelOptionalNo30—30External text-extraction timeout
DOCUMENT_BINARY_PDFTOTEXT_BINARYLaravelOptionalNopdftotext—pdftotextExecutable used for PDF text extraction

Search, analytics, and embeddings

VariableReceiverClassSecretLocalTestProductionEffect
SCOUT_DRIVERLaravel ScoutOptionalNodatabasedatabasedatabaseIndex synchronization engine
SCOUT_QUEUELaravel ScoutOptionalNofalsefalsetrueQueues index synchronization
SCOUT_AFTER_COMMITLaravel ScoutOptionalNotruetruetrueDefers index writes until transaction commit
TYPESENSE_HOSTLaravel ScoutConditionalNotypesense—blankTypesense host
TYPESENSE_PORTLaravel ScoutConditionalNo8108—443Typesense port
TYPESENSE_PROTOCOLLaravel ScoutConditionalNohttp—httpsTypesense protocol
TYPESENSE_API_KEYLaravel Scout, local TypesenseConditionalYesdevelopment admin key—blankServer-only administrative key
TYPESENSE_SCOPED_KEY_PARENTLaravel SearchConditionalYesdevelopment search-only key—blankExisting search-only parent used to sign tenant-scoped keys
KNOWLEDGE_SEARCH_SEMANTIC_ENABLEDLaravel KnowledgeOptionalNofalsefalsefalseEnables semantic reads for the selected immutable profile
KNOWLEDGE_SEARCH_EMBEDDING_PROFILELaravel KnowledgeOptionalNononenonenoneProvider/model/version/dimension/storage generation; no production profile exists
RESOURCE_IMPORT_HEADER_EMBEDDING_PROVIDERLaravel Resource ImportOptionalNononenonenoneEnables optional header-only semantic matching
RESOURCE_IMPORT_HEADER_EMBEDDING_BASE_URLLaravel Resource ImportConditionalNolocal Ollama URL—blankReachable Ollama /api/embed base URL
RESOURCE_IMPORT_HEADER_EMBEDDING_MODELLaravel Resource ImportConditionalNoembeddinggemma—embeddinggemmaHeader embedding model

Candidate retrieval follows SCOUT_DRIVER because the examples deliberately omit SEARCH_CANDIDATE_GATEWAY. Set that advanced override only when a staged cutover intentionally splits indexing from candidate retrieval. See Search Configuration Profiles for the full procedure. The production validator requires the complete Typesense connection whenever either SCOUT_DRIVER=typesense or SEARCH_CANDIDATE_GATEWAY=typesense selects that service.

Analytics

VariableReceiverClassSecretLocalTestProductionEffect
GOOGLE_ANALYTICS_ENABLEDLaravel/browserOptionalNofalse—trueEnables consent-gated GA4 collection
GOOGLE_ANALYTICS_MEASUREMENT_IDBrowserConditionalNoG-QQR7R8D9QS—G-QQR7R8D9QSPublic GA4 stream identifier
GOOGLE_ANALYTICS_COLLECT_SUBDOMAINSLaravel/browserOptionalNodevelopers—developersCentral subdomains allowed to collect
GOOGLE_ANALYTICS_COLLECT_TENANT_FIXTURESLaravel/browserOptionalNodemo—demoFixture tenants allowed to collect
ANALYTICS_PROPERTY_IDLaravel adminConditionalNo546439209—546439209GA4 property queried by server-side reporting
ANALYTICS_CREDENTIALS_PATHLaravel adminConditional localNoprivate storage path——Local service-account JSON path
ANALYTICS_CREDENTIALS_BASE64Laravel adminConditional productionYesblank—blankFilesystem-less service-account JSON
ANALYTICS_CACHE_STORELaravel adminOptionalNofile—redisReporting cache store
ANALYTICS_CACHE_MINUTESLaravel adminOptionalNo60—60Fresh report cache lifetime
ANALYTICS_STALE_CACHE_MINUTESLaravel adminOptionalNo10080—10080Stale-on-provider-failure lifetime
ANALYTICS_CLICK_DIMENSIONS_ENABLEDLaravel/browserOptionalNofalse—falseEnables click-dimension reporting
ANALYTICS_REQUEST_TIMEOUT_MILLISECONDSLaravel adminOptionalNo12000—12000GA4 request timeout
VariableReceiverClassSecretLocalTestProductionEffect
AGENT_JWT_PRIVATE_KEY_PATHLaravelConditional localNoprivate PEM pathblank—Local delegation-signing key path
AGENT_JWT_PUBLIC_KEY_PATHLaravelConditional localNopublic PEM pathblank—Local delegation-verification key path
AGENT_JWT_PRIVATE_KEY_BASE64Laravel CloudRequired for production AgentYesblank—blankFilesystem-less private PEM content
AGENT_JWT_PUBLIC_KEY_BASE64Laravel CloudRequired for production AgentNoblank—blankMatching public PEM content
AGENT_SERVICE_TOKENLaravel, Edge, GatewayRequired for AgentYesblankblankblankAuthenticates internal callbacks and derives the ticket prefilter HMAC
AGENT_EDGE_TOKENLaravel, EdgeRequired for AgentYesdevelopment tokenblankblankProtects Laravel-to-Worker /agent/* requests
NEXIA_CENTRAL_BASE_URLEdge, GatewayRequired for AgentNohttp://app:8000—Wrangler-managedLaravel bootstrap, ticket exchange, heartbeat, and callback base URL
AGENT_GATEWAY_URLLaravelRequired for AgentNolocal Edge URLtest Gateway URLWorker URLServer-side protected Edge endpoint
AGENT_PUBLIC_STREAM_URLLaravel/browserRequired for production AgentNolocal browser endpointblankWorker /browser/agent/streamExact no-redirect public ticket stream URL; DB rollout policy decides who uses it
AGENT_GATEWAY_PORTComposeOptional localNo8100——Host port for direct Gateway diagnostics
AGENT_CHECKPOINT_DSN_TEMPLATEGatewayRequired for production AgentYestenant DSN template—blankPer-tenant LangGraph checkpoint and durable usage-journal DSN with {tenant_id} substitution
AGENT_GATEWAY_LOG_LEVELGatewayOptionalNoINFO—Wrangler-managedGateway log severity
AGENT_GATEWAY_DEBUG_ERRORSGatewayOptional diagnosticsNofalse—code default false; optional Wrangler overrideExposes provider/tool exception detail to SSE clients when true
AGENT_SCREEN_SEARCH_EMBEDDING_PROVIDERGatewayOptionalNonone—Wrangler-managednone, ollama, gemini, or zai semantic reranker
AGENT_SCREEN_SEARCH_EMBEDDING_BASE_URLGatewayOptional provider overrideNoblank/code default—code default; optional Wrangler overrideGemini and Z.ai have hosted defaults; production Ollama needs a Container-reachable URL
AGENT_SCREEN_SEARCH_EMBEDDING_API_KEYGatewayConditional hosted providerYesblank—blankDedicated Gemini or Z.ai screen-search key, never a chat key
AGENT_SEARCH_PROVIDERLaravelOptionalNonone—noneEnables the self-hosted agent_search web-search bridge
AGENT_SEARCH_BASE_URLLaravelConditionalNohttp://agent-search:8000—blankReachable agent-search service URL
AGENT_SEARCH_TOKENLaravel, agent-searchConditionalYesblank—blankShared internal agent-search token
SEARXNG_SECRETSearXNG hostConditionalYesblank—blankGenerated secret for the optional self-hosted metasearch service

Cloudflare does not read a production .env file. wrangler.jsonc commits non-secret Worker values and the Container/rate-limit bindings. Register AGENT_EDGE_TOKEN, AGENT_SERVICE_TOKEN, AGENT_CHECKPOINT_DSN_TEMPLATE, and, when needed, AGENT_SCREEN_SEARCH_EMBEDDING_API_KEY with wrangler secret put. services/agent-gateway-edge/src/index.ts then forwards only its explicit, nonblank allowlist into the Python Container. Setting a dashboard variable that is absent from that allowlist does not configure the Gateway.

Langfuse, observability, and optional services

VariableReceiverClassSecretLocalTestProductionEffect
LANGFUSE_ENABLEDGatewayOptionalNofalse—falseEnables optional masked trace export; failure remains fail-open
LANGFUSE_HOSTGatewayConditionalNointernal Langfuse URL—blankLangfuse API base URL used by the Gateway exporter
LANGFUSE_PUBLIC_KEYGateway, bootstrapConditionalNodevelopment key—blankLangfuse project public key
LANGFUSE_SECRET_KEYGateway, bootstrapConditionalYesdevelopment key—blankLangfuse project secret key
LANGFUSE_MASK_CONTENTGatewayOptionalNotrue—trueMasks prompt and completion content before export
LANGFUSE_PORTLocal ComposeOptionalNo3300——Browser-published local Langfuse UI port
LANGFUSE_SALTLangfuse hostRequired outside localYesblank/dev fallback—blankServer hashing salt
LANGFUSE_ENCRYPTION_KEYLangfuse hostRequired outside localYesblank/dev fallback—blankServer data-encryption key
LANGFUSE_NEXTAUTH_SECRETLangfuse hostRequired outside localYesblank/dev fallback—blankLangfuse login/session secret
LANGFUSE_REDIS_DBLangfuse hostOptionalNo3—3Redis database isolated from Laravel cache/queue data
LANGFUSE_INIT_ORG_IDLangfuse bootstrapOptionalNonexia—nexiaInitial organization id
LANGFUSE_INIT_PROJECT_IDLangfuse bootstrapOptionalNonexia-agent—nexia-agentInitial project id
LANGFUSE_INIT_USER_EMAILLangfuse bootstrapRequired outside localNo${ADMIN_SEEDER_EMAIL}—blankInitial owner login
LANGFUSE_INIT_USER_NAMELangfuse bootstrapOptionalNoNexia Dev—Nexia AdminInitial owner display name
LANGFUSE_INIT_USER_PASSWORDLangfuse bootstrapRequired outside localYes${ADMIN_SEEDER_PASSWORD}—blankInitial owner password
LANGFUSE_NEXTAUTH_URLSelf-hosted LangfuseConditionalNo——blankBrowser-facing authentication callback URL
FORWARD_LANGFUSE_PORTSelf-hosted ComposeOptionalNo——127.0.0.1:3300Loopback-only Langfuse UI binding

Sentry is a separate optional Laravel error and trace export:

VariableReceiverClassSecretLocalTestProductionEffect
SENTRY_LARAVEL_DSNLaravelOptionalYesblank——Enables Sentry error delivery when nonblank
SENTRY_TRACES_SAMPLE_RATELaravelOptionalNo0——Performance trace sampling rate

LANGFUSE_ENABLED=true requires a complete host and project keypair in the Gateway runtime. When the self-hosted bootstrap is used, its seeded project keypair must match the Gateway exporter. The production validator requires the host and keypair. The tenant: trace-tag prefix is Gateway-owned and has no environment override. Product usage metering is independent of Langfuse.

Compatibility aliases and internal values

Do not add these as normal keys in a new environment.

NamesStatusReplacement or owner
APPROVAL_FILE_SCANNER, APPROVAL_CLAMD_HOST, APPROVAL_CLAMD_PORT, APPROVAL_CLAMD_CONNECT_TIMEOUT_SECONDS, APPROVAL_CLAMD_SCAN_TIMEOUT_SECONDSRead-only compatibility aliases; absent from the current catalogsMALWARE_SCANNER and CLAMD_*
MAIL_ENCRYPTIONCompatibility assignment with local value nullMAIL_SCHEME takes precedence; do not add the older name to production
RESOURCE_IMPORT_EMBEDDING_PROVIDER, RESOURCE_IMPORT_EMBEDDING_BASE_URL, RESOURCE_IMPORT_EMBEDDING_MODELOne-release read fallbackRESOURCE_IMPORT_HEADER_EMBEDDING_*
SEARCH_SEMANTIC_ENABLED, SEARCH_SEMANTIC_PROVIDEROne-release read fallbackKNOWLEDGE_SEARCH_SEMANTIC_ENABLED, KNOWLEDGE_SEARCH_EMBEDDING_PROFILE
AGENT_OLLAMA_EMBEDDING_MODEL, AGENT_GEMINI_EMBEDDING_MODEL, AGENT_ZAI_EMBEDDING_MODELRemoved operator knobsGateway code owns the provider model constants
AGENT_GATEWAY_SSE_KEEPALIVE_SECONDS, AGENT_GATEWAY_SSE_BUFFER_MAX_BYTES, AGENT_GATEWAY_SSE_BUFFER_MAX_FRAMES, AGENT_MANIFEST_FETCH_MAX_ATTEMPTSRemoved operator knobsCross-runtime protocol and safety constants are code-owned
AGENT_EDGE_LOCAL_HOST, AGENT_EDGE_LOCAL_PORT, AGENT_GATEWAY_UPSTREAM_URLLocal adapter internals fixed by ComposeNot operator registrations
QUERY_LOG_RETENTION_DAYS, FETCH_LOG_RETENTION_DAYS, SEARXNG_BASE_URLSearch-container internalsCompose and tracked patches own them
LANGFUSE_TENANT_TAG_PREFIXRemoved operator knobThe Gateway owns the code-defined tenant: trace-tag prefix
PLAYWRIGHT_BROWSERS_PATH, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD, PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, DATA_DIRagent-search image internalsDockerfile owns them
HOSTNAME, DATABASE_URL, SALT, ENCRYPTION_KEY, CLICKHOUSE_*, LANGFUSE_S3_EVENT_UPLOAD_*, REDIS_CONNECTION_STRING, TELEMETRY_ENABLED, NEXTAUTH_*, LANGFUSE_INIT_PROJECT_PUBLIC_KEY, LANGFUSE_INIT_PROJECT_SECRET_KEY, MINIO_ROOT_*Derived or fixed Langfuse container environment; several contain secretsCompose maps operator-owned LANGFUSE_*, database, and bootstrap values into these process names; LANGFUSE_INIT_PROJECT_ID remains an operator setting
VITE_APP_NAMEDead name with no current readerUse APP_NAME; do not restore the duplicate Vite assignment
POSTMARK_MESSAGE_STREAM_ID, TYPESENSE_MAX_TOTAL_RESULTS, SEARXNG_SEARCH_FORMATSInactive, comment-only, or unsupported by the selected imageNot operator registrations
AGENT_GATEWAY_CONTAINER, AGENT_BROWSER_STREAM_RATE_LIMITERCloudflare bindings, not environment variableswrangler.jsonc owns them
PYTHONDONTWRITEBYTECODE, PYTHONUNBUFFERED, PIP_DISABLE_PIP_VERSION_CHECK, UV_LINK_MODE, UV_PROJECT_ENVIRONMENTGateway image constantsDockerfile owns them
WWWGROUP, WWWUSER, AGENT_SEARCH_REFLocal build argumentsCompose/Docker build owns them; the search ref stays security-pinned
LANGFUSE_TEST_HOSTIntegration-test-only endpointNot an operator registration
NEXIA_CONTRIBUTION_MANIFEST_PATHGenerated contribution-cache path overrideCode owns the normal path; not a deployment registration
NEXIA_SIGNATURE_LIVE_FIXTURE_PASSWORD, DEMO_ADMIN_PASSWORDLocal fixture command/seeder inputs; secretsDevelopment-only and never production catalog values
GOOGLE_OIDC_CLIENT_ID, GOOGLE_OIDC_CLIENT_SECRET, ENTRA_OIDC_CLIENT_ID, ENTRA_OIDC_CLIENT_SECRET, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_ISSUERDevelopment SSO seeder inputs; secrets where namedProduction identity provider configuration is database-owned, not environment-owned
NO_COLOR, TERM, PATHAmbient shell/process environmentThe operating system owns them
NEXIA_APP_IMAGE, NEXIA_AGENT_GATEWAY_IMAGEOptional self-hosted Compose image inputsdocker-compose.prod.yml only; not part of the managed production catalog

Options

Source-supported overrides outside the official catalogs

Current source can read the following names, but Nexia deliberately omits them from the supported local and production assignment catalogs. Most are upstream framework escape hatches, diagnostics, or safety constants whose code defaults should remain aligned. Treat them as advanced overrides, not values that every deployment should copy. Promote one into an official catalog only after its runtime owner, validation rule, and production need are explicit.

VariableReceiverClassSecretDefaultEffect / reason omitted
APP_PREVIOUS_KEYSLaravelOptional rotationYesblankComma-separated former application keys accepted during planned key rotation
CLAMD_EXPECTED_VERSIONLaravel healthOptionalNo1.4Image/readiness contract; change only with the pinned scanner release
MAIL_URLLaravel mailOptionalYesblankUpstream complete SMTP DSN override
MAIL_EHLO_DOMAINLaravel mailOptionalNohost from APP_URLUpstream SMTP EHLO domain override
MAIL_SENDMAIL_PATHLaravel mailConditionalNo/usr/sbin/sendmail -bs -iCommand used when MAIL_MAILER=sendmail
MAIL_LOG_CHANNELLaravel mailOptionalNodefault log channelDedicated channel used when MAIL_MAILER=log
POSTMARK_API_KEYLaravel mailConditionalYesblankRequired when MAIL_MAILER=postmark
RESEND_API_KEYLaravel mailConditionalYesblankRequired when MAIL_MAILER=resend
SEARCH_CANDIDATE_GATEWAYLaravel SearchOptional staged cutoverNotypesense when Scout uses Typesense, otherwise databaseOverrides candidate retrieval independently of indexing; leave unset for the ordinary profile
SCOUT_PREFIXLaravel ScoutOptionalNoblankPrefixes external index names
SCOUT_IDENTIFYLaravel ScoutOptionalNofalseEnables supported engine user identification
TYPESENSE_PATHLaravel ScoutOptionalNoblankURL path for hosted Typesense
TYPESENSE_CONNECTION_TIMEOUT_SECONDSLaravel ScoutOptionalNo2Connection timeout
TYPESENSE_HEALTHCHECK_INTERVAL_SECONDSLaravel ScoutOptionalNo30Node health-check cadence
TYPESENSE_NUM_RETRIESLaravel ScoutOptionalNo3Client retry count
TYPESENSE_RETRY_INTERVAL_SECONDSLaravel ScoutOptionalNo1Retry delay
TYPESENSE_IMPORT_ACTIONLaravel ScoutOptionalNoupsertBulk import action
AGENT_VISION_MODELSLocal/self-hosted Gateway onlyOptionalNoblankImage-capable local-model prefix allowlist; Cloudflare intentionally does not forward it, pending catalog-owned model capability metadata
SIGNATURE_TEMPLATE_MAXIMUM_SIGNERSLaravel SignatureOptionalNo8Boot default for the maximum signer count
SIGNATURE_LOCAL_FIXTURE_PROFILELaravel SignatureOptional local/testNoblankSelects an explicitly named deterministic fixture profile
SIGNATURE_BULK_REQUEST_STUCK_AFTER_SECONDSLaravel SignatureOptionalNo900Age used for bulk readiness metadata
SIGNATURE_BULK_REQUEST_RECOVERY_SCAN_LIMITLaravel SignatureOptionalNo100Maximum bulk rows examined by one recovery scan
SIGNATURE_STUCK_AFTER_SECONDSLaravel SignatureOptionalNo900Age used by the stuck-operation query
SIGNATURE_STUCK_QUERY_LIMITLaravel SignatureOptionalNo100Maximum stuck operations returned per query
SIGNATURE_ARTIFACT_RETENTION_YEARSLaravel SignatureOptionalNo7Default immutable artifact/evidence retention period
SIGNATURE_DOMPDF_EXPECTED_VERSIONLaravel healthOptionalNo3.1.6Expected Dompdf runtime version
SIGNATURE_FPDI_EXPECTED_VERSIONLaravel healthOptionalNo2.6.8Expected FPDI runtime version
SIGNATURE_TCPDF_EXPECTED_VERSIONLaravel healthOptionalNo6.11.3Expected TCPDF runtime version

Production now publishes canonical MALWARE_SCANNER=clamd and CLAMD_* names. Supply a reachable private CLAMD_HOST. The production validator reads the canonical names first and accepts the older aliases only during their compatibility window.

Apply changes

Laravel reads environment values through config/*.php; Vite exposes VITE_* values to browser code, so never put secrets there. Compose interpolates service configuration, and the Gateway reads process settings at startup.

After changing Laravel configuration, clear cached configuration and restart the affected long-lived process. After changing a Cloudflare secret or Wrangler variable, deploy a new Worker/Container version; changing Laravel Cloud does not inject that value into Cloudflare. A production registration is complete only when every receiving owner has the same shared secret where the table names more than one runtime.

Laravel Cloud variables      Laravel config and PHP workers
Wrangler vars/bindings       Public Worker topology and Container settings
Cloudflare secrets           Edge trust, checkpoint, and Gateway credentials
External service host env    ClamAV, Typesense, Langfuse, SearXNG, and similar services

Errors

Error or observable stateCauseResolution
Production environment file not found: ...The validator received a nonexistent export pathRerun it with the actual exported file
APP_KEY must be a generated base64 key and must not contain CHANGE_ME.Production catalog placeholder was validatedGenerate the Laravel key in the target secret store
<KEY> is missing or contains a placeholder.A required production value is blank or still an example valueSupply it to the owner named in this page, then rerun scripts/validate-prod-env.sh
AGENT_EDGE_TOKEN must not use the known local development token.Production still contains the public local example tokenGenerate a new token and register the same value in Laravel Cloud and Cloudflare
<KEY> must be an absolute HTTPS URL without userinfo, query, fragment, or whitespace.A production endpoint is unsafe or malformedRegister its canonical HTTPS origin/URL without embedded credentials or query data
AGENT_PUBLIC_STREAM_URL must use the exact /browser/agent/stream path.The browser stream URL points at a redirect, relay, or wrong routeRegister the Worker's exact public Direct SSE endpoint
MALWARE_SCANNER must be clamd in production.Production selected the local passthrough waiver or another driverDeploy reachable ClamD and use the canonical scanner settings
<KEY> must be a deployment-reachable host name or address without a scheme, path, credentials, or whitespace.A service host contains a URL or credentialStore only the reachable host name in the host variable
<KEY> must be an integer between 1 and 65535.A service port is malformed or outside the TCP rangeRegister the receiving service's valid port
TYPESENSE_PROTOCOL must be one of: http https.Typesense is selected with an unsupported schemeUse https for hosted production or the intentional internal http endpoint
PRODUCT_STORAGE_DRIVER must be one of: local s3.The product disk family is unsupported or blankSelect the self-contained local profile or configure the full S3-compatible block
AGENT_SCREEN_SEARCH_EMBEDDING_PROVIDER must be one of: none ollama gemini zai.The Gateway reranker provider is unknownChoose a supported provider or none
AGENT_SCREEN_SEARCH_EMBEDDING_BASE_URL for a hosted provider must be an absolute HTTPS URL without userinfo, query, fragment, or whitespace.A custom Gemini/Z.ai endpoint is unsafe or malformedRemove the override to use the code default, or register a clean HTTPS base URL
RESOURCE_IMPORT_HEADER_EMBEDDING_PROVIDER must be one of: none ollama.Resource Import selected an unsupported embedding providerUse reachable Ollama or keep header embeddings disabled
KNOWLEDGE_SEARCH_SEMANTIC_ENABLED must be a boolean value.The feature flag is not a recognized booleanUse true or false
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE must select a production-approved profile when Knowledge semantic search is enabled.Semantic reads are enabled with none or a blank profileDisable semantic reads until an approved immutable profile exists
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE deterministic-local-test-vector-16-v1 is not allowed in production.The deterministic test profile leaked into productionReturn to none; it is a local/test fixture only
LANGFUSE_ENABLED must be a boolean value.The optional tracing switch is not a recognized booleanUse true or false
VITE_REVERB_APP_KEY must equal REVERB_APP_KEY.Server and browser Reverb application keys differUse the same platform-managed public key
AGENT_JWT_PRIVATE_KEY_BASE64 must be the Base64 of a PEM key.The decoded private key is not PEM key materialRegister the one-line output of base64 -i private.pem in Laravel Cloud
Agent gateway environment variable '<KEY>' is not set. The request cannot proceed until it is populated.Edge did not forward a required Container value, or the secret is absentRegister it in Cloudflare and confirm src/index.ts forwards the canonical name
ticket_service_unavailableEdge lacks NEXIA_CENTRAL_BASE_URL, AGENT_SERVICE_TOKEN, or the rate-limit bindingRestore the Worker variable, secret, and binding before retrying
Gateway health is configured: falseNEXIA_CENTRAL_BASE_URL or AGENT_SERVICE_TOKEN is emptyConfigure both in the Gateway runtime
Screen-search health is misconfiguredA hosted provider lacks its API keyFill the canonical screen-search key or select none; readiness validates shape, not provider reachability
ANALYTICS_CREDENTIALS_BASE64 must contain valid Base64.The service-account JSON encoding is damagedRe-register the JSON as single-line Base64
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE '<PROFILE>' is not implemented by this release.Production selected an unsupported semantic generationReturn to none and keep semantic retrieval disabled
Langfuse is enabled but traces remain emptyThe Gateway has an incomplete host/keypair or is not exporting tracesConfigure the Gateway with the Langfuse project's host/keypair and inspect export health; product usage is independent of Langfuse
Candidate search uses a different engine than indexingAn operator set SEARCH_CANDIDATE_GATEWAY explicitlyRemove the override to follow Scout, or complete the deliberate split profile
Agent web search health succeeds but actual search returns 502The SearXNG pair, JSON format configuration, or secret is missingConfigure both containers in the search profile and set SEARXNG_SECRET
Protected uploads remain unavailableProduction CLAMD_HOST is blank or unreachableRegister the reachable private scanner hostname under canonical CLAMD_HOST
Tenant switching causes 419 or logoutSessions use a tenant-prefixed cache store or a domain-wide cookieKeep SESSION_STORE=session and leave production SESSION_DOMAIN unset

Real usage

Local Agent injection is visible in docker-compose.yml: the same AGENT_SERVICE_TOKEN reaches the local Edge and Gateway, while the Edge adapter uses fixed internal URLs. Cloudflare production uses a different mechanism:

Code example
Shell
(
cd services/agent-gateway-edge
pnpm exec wrangler secret put AGENT_EDGE_TOKEN
pnpm exec wrangler secret put AGENT_SERVICE_TOKEN
pnpm exec wrangler secret put AGENT_CHECKPOINT_DSN_TEMPLATE
# Only with Gemini or Z.ai screen search:
pnpm exec wrangler secret put AGENT_SCREEN_SEARCH_EMBEDDING_API_KEY
# Only with Langfuse tracing:
pnpm exec wrangler secret put LANGFUSE_ENABLED
pnpm exec wrangler secret put LANGFUSE_HOST
pnpm exec wrangler secret put LANGFUSE_PUBLIC_KEY
pnpm exec wrangler secret put LANGFUSE_SECRET_KEY
)

The screen-search embedding secret command is needed only for Gemini or Z.ai. The four Langfuse commands are needed only when optional tracing is enabled; use the values owned by the Langfuse project (and by the self-hosted bootstrap when that profile is used). Store non-secret screen-search settings in wrangler.jsonc and secrets with Wrangler. services/agent-gateway-edge/wrangler.jsonc owns NEXIA_CENTRAL_BASE_URL, the screen-search provider, Gateway log level, Container binding, and rate limiter. Add the optional screen-search base URL there only when overriding the Gateway default. services/agent-gateway-edge/src/index.ts is the final authority for which values enter the Container.

From the Core root, save the production owners’ export to the ignored tmp/production-env-export.env, then validate it before rollout. This file contains secrets; do not substitute the local development .env or commit the export:

Code example
Shell
bash scripts/validate-prod-env.sh tmp/production-env-export.env

This check covers framework safety, Agent trust/endpoints/JWT and checkpoint settings, the three embedding capability contracts, conditional Typesense credentials, canonical ClamAV configuration, and the complete Langfuse host/keypair when enabled. It validates configuration shape; it does not prove that an external service is reachable from its receiving runtime.

Source of truth: docs/developers/content/en/operations/environment-variables.md