Documentation

Production environment variables

Look up the production image, origin, domain, secret, storage, authentication, email, proxy, worker, and lifecycle settings Nibleaf consumes.

  • 8 min read
  • Updated Aug 31, 2026

Start from .env.production.example shipped with the release. This page explains the setting groups, but the template and Compose file determine what that release actually consumes. Never commit a populated .env.

Image and public application

VariableRequiredDefaultPurpose
NIBLEAF_VERSIONYes in practicev0.1.2 in the current templateGHCR release tag. Pin an existing release; avoid floating tags. The manual Docker workflow rejects overwriting an existing v* release tag, making published version tags immutable by repository policy.
APP_URLYesNoneBrowser-facing dashboard and normal authentication origin, without a trailing slash.
ADMIN_URLOnly when admin is exposedhttp://localhost:4315Public origin for the optional operator console.
NIBLEAF_BINDNo127.0.0.1Host interface for the app port. Keep loopback when the proxy is local.
APP_PORTNo4310Host port mapped to the app container.
BETTER_AUTH_URLNoAPP_URLExplicit authentication base override.
TRUSTED_ORIGINSNoAPP_URLComma-separated authentication origins. Include both APP_URL and ADMIN_URL when the admin console is exposed so native support impersonation can begin there.
CORS_ALLOWED_ORIGINSNoAPP_URLComma-separated API origins. Include both APP_URL and ADMIN_URL when the admin console calls the shared API directly.
PINO_LOG_LEVELNoinfo in productionMinimum structured log level.
PINO_LOG_FILENoEmptyOptional JSONL disk destination in addition to terminal output. Mount the parent directory to persist container logs.

Published documentation domains

VariableRequiredDefaultPurpose
SITE_BASE_DOMAINNoEmptyEnables <project>.<base-domain> publishing; requires wildcard DNS and TLS.
CUSTOM_DOMAIN_CNAME_TARGETNoSITE_BASE_DOMAINOperator-controlled CNAME target shown to custom-domain owners.
CUSTOM_DOMAIN_PROVIDERNoingressCustom-domain automation strategy supported by the release.
CLOUDFLARE_SAAS_ZONE_IDFor Cloudflare for SaaSEmptyZone identifier for managed custom hostnames.
CLOUDFLARE_SAAS_API_TOKENFor Cloudflare for SaaSEmptyNarrow token for custom-hostname operations.
CLOUDFLARE_SAAS_WORKER_SCRIPTNonibleaf-custom-domain-edgeEdge worker script name.
CUSTOM_DOMAIN_EDGE_SECRETFor the managed edge pathEmptyShared edge-to-origin authentication secret.

Required secrets

VariableRequiredPurpose
BETTER_AUTH_SECRETYesSigns authentication state. Generate independently with openssl rand -hex 32.
POSTGRES_PASSWORDYesPassword for the bundled Nibleaf database user.
INTERNAL_API_SECRETStrongly recommendedAuthenticates trusted app-to-API hints used for accurate rate limiting.

Object storage

VariableRequiredDefaultPurpose
STORAGE_PROVIDERNomaxioProvider behavior such as maxio, r2, or another supported S3-compatible mode.
STORAGE_ENDPOINTFor external storagehttp://maxio:9000Server-to-storage endpoint.
STORAGE_PUBLIC_ENDPOINTYesNoneBrowser-reachable origin used for presigned requests.
STORAGE_ACCESS_KEY_IDYesNoneBucket access identifier.
STORAGE_SECRET_ACCESS_KEYYesNoneBucket secret. Generate independently.
STORAGE_BUCKETNonibleafAsset and export bucket.
STORAGE_REGIONNoautoS3 region value.
STORAGE_FORCE_PATH_STYLENotrueUse path-style bucket URLs; AWS S3 commonly uses false.
STORAGE_PUBLIC_URLRecommendedEmptyPublic asset base, often a bucket or CDN URL.
STORAGE_CORS_ALLOWED_ORIGINSNoAPP_URLBrowser origins allowed to upload directly.
STORAGE_AUTO_CORSNotrueLet Nibleaf configure supported bucket CORS automatically.
MAXIO_SECURE_COOKIESNotrueRequire HTTPS for bundled maxio console cookies.

Authentication and email

VariableRequiredDefaultPurpose
DISABLE_SIGNUPNofalseClose new registration while preserving existing sign-in.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETFor Google sign-inEmptyOAuth client credentials.
EMAIL_FROMFor deliverynibleaf@localhostProvider-verified sender.
POSTMARK_API_KEYFor PostmarkEmptyServer token; preferred when set.
POSTMARK_MESSAGE_STREAMNoEmptyPostmark stream.
SMTP_URLFor SMTP fallbackEmptyFull SMTP connection URL. Protect it as a secret.
EMAIL_DELIVERY_REQUIREDNotrue in productionReturn an unhealthy worker status and fail queued email jobs when no provider is configured.

Google OAuth

Create a Web application OAuth client in Google Cloud, then configure:

  • Authorized JavaScript origin: the exact APP_URL, such as https://nibleaf.example.com.
  • Authorized redirect URI: ${APP_URL}/api/auth/callback/google.
  • GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET: the matching client credentials.

Both variables must be present and non-blank after trimming surrounding whitespace. Nibleaf hides the Google button when either value is missing, so a partially configured provider cannot send readers into a broken sign-in flow. Restart the application after changing these server-side values.

Optional product and traffic controls

VariableRequiredDefaultPurpose
OPENROUTER_API_KEYOnly for AI featuresEmptyEnables editor drafting, embeddings, and optional grounded answers through OpenRouter.
AI_DRAFT_MODELNoopenai/gpt-4o-miniOpenRouter model used for explicit editor writing actions.
AI_DAILY_LIMITNoApplication defaultPer-workspace daily AI request limit; 0 disables drafting.
MARKETING_GTM_IDNoEmptyPreferred GTM container ID for public instance marketing pages. It is public metadata and loads only after explicit visitor consent. Configure the GA4 Google tag in GTM with automatic pageviews disabled; Nibleaf pushes one manual page_view per accepted route plus allowlisted events. This variable takes precedence over MARKETING_GA4_ID.
MARKETING_GA4_IDNoEmptyLegacy direct-GA4 fallback for existing self-hosters. It loads only after explicit consent and is ignored when MARKETING_GTM_ID is configured.
RATE_LIMIT_PUBLIC_PER_MINNoApplication defaultPublic site-serving requests per address per minute.
TRUSTED_PROXY_HOPSNo0Count of trusted public proxies that append to the forwarding chain.

GTM container contract

When MARKETING_GTM_ID is enabled, configure one Google tag in GTM with automatic pageviews disabled and its normal page initialization trigger. Then configure one GA4 Event tag triggered by the Custom Event nibleaf_marketing_event, with its GA event name read from the Data Layer Variable event_name. Nibleaf uses that stable envelope for the allowlisted names page_view, sign_up, cta_clicked, free_tool_started, free_tool_completed, and free_tool_cta_clicked, so six separate GTM Event tags are not required. Map only the documented safe event variables. Do not add variables that read form fields, account data, document content, or arbitrary DOM values into analytics. Keep consent checks enabled on both tags. Nibleaf loads the container only after acceptance, pushes one manual page_view for the accepted route and each later SPA navigation, and stops event delivery when consent is withdrawn.

Operator and lifecycle settings

Model Context Protocol

VariableRequiredDefaultPurpose
MCP_ENABLEDNofalseEnables the authenticated project-bound /api/mcp endpoint. Keep it disabled until proxy and key-lifecycle checks pass.
MCP_ALLOWED_HOSTSNoEmptyComma-separated additional public hostnames. API_URL and APP_URL hosts are already allowed. Schemes, paths, wildcard values, and ambiguous forwarded chains are rejected.
MCP_RATE_LIMIT_PER_MINNo120Per-key requests accepted by one API process per minute. Add an ingress/shared-edge limit for deployment-wide enforcement.

See secure MCP client setup and operations before enabling the endpoint. API-key secrets are project-admin managed, displayed once, and must not be stored in environment examples or repository configuration.

Export workers

VariableRequiredDefaultPurpose
EXPORT_CHROMIUM_PATHFor PDF outside the official image/usr/bin/chromium-browserChromium-compatible executable used for PDF rendering.
EXPORT_CONCURRENCYNo2Export jobs processed by one worker; accepted range is 1–8.
EXPORT_MAX_ACTIVE_PER_PROJECTNo3Concurrent project runs accepted by the API.
EXPORT_MAX_DAILY_PER_PROJECTNo20Per-project daily run limit.
EXPORT_MAX_PAGESNo5000Maximum pages copied into one immutable export snapshot.
EXPORT_MAX_SNAPSHOT_BYTESNo52428800Maximum serialized snapshot bytes.
EXPORT_MAX_ASSET_BYTESNo262144000Maximum referenced asset bytes copied into an artifact.
EXPORT_MANUAL_RETENTION_DAYSNo7Retention for one-time export runs.
EXPORT_DOWNLOAD_TTL_SECONDSNo300Presigned download lifetime; accepted range is 30–900 seconds.

The official image includes Chromium. If WORKER_QUEUES is a comma-separated allowlist, include export; an empty value enables every queue.

Bidirectional Git

VariableRequiredDefaultPurpose
GIT_CREDENTIAL_ENCRYPTION_KEYTo enable two-way GitNoneExactly 32 bytes encoded as base64; encrypts provider credentials and webhook secrets.
GIT_WORKER_SECRETTo enable two-way GitNoneAt least 32 characters shared by API and worker for opaque callbacks.
GIT_CONCURRENCYNo2Git operations processed by one worker.

Generate the two secrets independently. Do not rotate the encryption key in place: existing ciphertext cannot be decrypted with a new key. Follow the Git authoring rotation procedure. If WORKER_QUEUES is set, include git.

Project integrations

VariableRequiredDefaultPurpose
INTEGRATION_CREDENTIAL_ENCRYPTION_KEYTo create project webhook connectionsNoneIndependent 32-byte base64 key for versioned AES-256-GCM credential envelopes and purpose-separated HMAC digests. Do not reuse the Git key.
INTEGRATION_CREDENTIAL_PREVIOUS_KEYSDuring key rotation onlyEmptyComma-separated prior integration keys accepted for decrypt and digest lookup during a bounded dual-read window.
INTEGRATION_CONFIRMATION_TTL_SECONDSNo300Lifetime of a one-time, revision-bound integration delete confirmation; accepted range is 60–1800 seconds.
INTEGRATION_CONFIRMATION_RETENTION_HOURSNo24Retention for consumed confirmation tombstones before bounded cleanup; accepted range is 1–168 hours. Expired unconsumed challenges are removed on the next project challenge.
INTEGRATION_IDEMPOTENCY_TTL_HOURSNo24Retention for secret-free durable mutation replays; accepted range is 1–168 hours.

Follow the rotation and rollback procedure in Integrations engine.

General operator settings

VariableRequiredDefaultPurpose
WORKBENCH_USER, WORKBENCH_PASSRecommendedEmptyBasic authentication for worker operations at port 4312.
NIBLEAF_RUN_SEEDNofalseSeed demo content during migration; keep false in production.
SERVER_SHUTDOWN_TIMEOUT_MSNo25000API drain timeout in milliseconds.
NIBLEAF_SHUTDOWN_GRACENo30sContainer stop grace; keep longer than the server timeout.

After changing origins, secrets, or storage, recreate the affected services and repeat the workflow checks in production readiness.