Skip to content

Configuration reference

Environment files contain production secrets

Keep .env.prod mode 0600, outside version control, and accessible only to the owning host administrators. Share individual cross-host values through a protected channel, never by copying the whole file.

Use .env.prod.example as the production key inventory. Create .env.prod with scripts/generate-production-env.sh or copy the template, keep it mode 0600, and never commit it. A variable is required only on hosts running its owning profile.

Runtime product policy is not an environment variable. Manage it through Platform settings.

Control plane

VariableRequiredMeaning and default
APP_KEYcontrolLaravel encryption key; required, retained with backups
EDGE_ARTIFACT_SIGNING_KEYcontrolIndependent high-entropy Ed25519 signing seed
APP_URLcontrolCanonical public control-panel URL
SESSION_SECURE_COOKIEHTTPS controlSecure-cookie flag; production default true
CONTROL_BINDcontrolHost publication for web; default 127.0.0.1:8080
CONTROL_HOSTNAMEcontrol overlayPublic browser/API hostname
TELEMETRY_HOSTNAMEcontrol overlayPublic telemetry-ingest hostname
CONTROL_PUBLIC_IPV4_ALLOWLISTDNS API gatewayExact control/worker sources allowed to call PowerDNS
EDGE_PUBLIC_IPV4_ALLOWLISTtelemetry gatewayExact edge/Vector ingestion sources
CONTROL_DB_PASSWORDlocal control DBPostgreSQL password for database cdnf
REDIS_PASSWORDlocal ValkeyRequired Valkey password
DB_URLexternal DBFull PostgreSQL URL; empty uses individual DB fields
DB_HOSTcontrolDefault control-db
DB_PORTcontrolDefault 5432
DB_SSLMODEcontrolDefault prefer; use verified TLS across hosts
REDIS_URLexternal ValkeyFull URL; empty uses host and port
REDIS_HOSTcontrolDefault redis
REDIS_PORTcontrolDefault 6379
METRICS_TOKEN_FILEcontrol/telemetryAbsolute mode-0600 bearer-token file

The Compose file fixes APP_ENV=production, APP_DEBUG=false, DB_CONNECTION=pgsql, database/user cdnf, CACHE_STORE=redis, SESSION_DRIVER=redis, QUEUE_CONNECTION=redis, REDIS_CLIENT=predis, CLICKHOUSE_DATABASE=cdnf, CLICKHOUSE_USER=cdnf, and GEOIP_DATABASE=/mmdb/GeoLite2-City.mmdb.

Backup

VariableRequiredMeaning and default
RESTIC_REPOSITORYcontrolEncrypted off-host Restic repository
RESTIC_PASSWORD_FILEcontrolAbsolute password-file path
BACKUP_ACCESS_KEY_IDS3 repositoryPrefix-scoped access key
BACKUP_SECRET_ACCESS_KEYS3 repositoryPrefix-scoped secret
BACKUP_DEFAULT_REGIONS3 repositoryDefault us-east-1
BACKUP_RESTORE_ALLOWEDrestore executorMust be true in explicit maintenance context; default false

Managed TLS

VariableRequiredMeaning and default
ACME_ENABLEDcontrolCompose sets true
ACME_CONTACT_EMAILcontrolACME account contact
ACME_DIRECTORY_URLcontrolLet's Encrypt production directory by default
ACME_ORDER_BUDGET_PER_HOURcontrolNew-order ceiling; default 20
ACME_VERIFY_TLSoptionalVerify ACME directory TLS; default true, false only for local Pebble
ACME_RENEW_BEFORE_DAYSoptionalRenewal window; default 30
ACME_DNS_TTLoptionalChallenge TTL; default 60
ACME_CHALLENGE_LIFETIME_MINUTESoptionalChallenge expiry; default 120
ACME_INITIAL_JITTER_SECONDSoptionalInitial spread; default 300
TLS_EXPIRY_ALERT_DAYSoptionalAdministrator expiry warning; default 14

Managed WAF

VariableRequiredMeaning and default
WAF_RULESET_VERSIONoptional control-plane labelImmutable WAF runtime identifier recorded in signed snapshots and telemetry; default owasp-crs/4.26.0-modsecurity/3.0.14. Change it only with the matching pinned edge image rollout.

Authoritative DNS

VariableRequiredMeaning and default
PDNS_DB_PASSWORDDNSPowerDNS PostgreSQL password
PDNS_API_KEYDNSPrivate PowerDNS API credential
DNS_BIND_V4DNSDNSdist IPv4 publication; default 0.0.0.0
PDNS_CA_CERTIFICATEcontrol workerTrust anchor for HTTPS PowerDNS API gateways
EDGE_GATEWAY_BINDINGSedge agentOptional rollout override. When absent, the agent fetches the bounded, revisioned edge/pool endpoint candidate over mTLS; when set, this static JSON remains authoritative.
EDGE_GATEWAY_STATUS_URLedge agentGateway metrics URL used for heartbeat readiness
EDGE_GATEWAY_METRICS_ADDRESSedge gatewayRestricted metrics listener; production default 0.0.0.0:9105
EDGE_GATEWAY_MAX_CONNECTIONSedge gatewayGlobal accepted-connection bound, 12865536 (default 8192)
DNS_API_HOSTNAMEDNS overlayDNS API TLS hostname
DNS_API_SERVER_CERTIFICATEDNS overlayAbsolute server certificate path
DNS_API_SERVER_PRIVATE_KEYDNS overlayAbsolute mode-0600 key path

Telemetry and GeoIP

VariableRequiredMeaning and default
CLICKHOUSE_PASSWORDtelemetry/control queryClickHouse password
CLICKHOUSE_URLtelemetry/control queryLocal http://clickhouse:8123 or verified external endpoint
CLICKHOUSE_DATABASEinternal/defaultDatabase queried by Laravel; Compose fixes cdnf
GEOIP_DATABASEedge runtimeMMDB file path; Compose fixes /mmdb/GeoLite2-City.mmdb
PROMETHEUS_URLoptional controlDefault http://prometheus:9090
VECTOR_METRICS_URLoptional controlVector metrics probe URL when overridden
METRICS_TOKENoptional controlDirect metrics bearer token fallback; prefer METRICS_TOKEN_FILE
MMDB_STALE_HOURSoptional controlHealth threshold; default 48
MMDB_PROVIDERupdaterdbip-jsdelivr default, dbip-official, ip66, or generic
MMDB_TARGET_FILEupdaterDefault GeoLite2-City.mmdb
MMDB_DOWNLOAD_INTERVAL_SECONDSupdaterDefault 86400, clamped to at least 300
MMDB_DOWNLOAD_RETRIESupdaterDefault 5
MMDB_EXPECTED_SHA256updaterOptional lowercase candidate checksum
MMDB_DOWNLOAD_URLcustom updaterHTTPS artifact URL
MMDB_DOWNLOAD_HEADERcustom updaterOptional authorization header; treat as secret

Vector receives CLICKHOUSE_ENDPOINT, CLICKHOUSE_USER, and CLICKHOUSE_PASSWORD from Compose. MMDB_DIR is an internal updater override whose default is /mmdb.

Images and host publication

VariableRequiredMeaning and default
CDNF_RELEASEevery production hostExact commit SHA or exact release tag
PUBLIC_BIND_IPV4multi-host overlayExact public IPv4 owned by the host
PUBLIC_BIND_IPV6IPv6 overlayExact public IPv6; omit the overlay when absent
EDGE_QUARANTINE_HTTP_BINDedgeQuarantine HTTP, default 127.0.0.1:18080
EDGE_QUARANTINE_HTTPS_BINDedgeQuarantine HTTPS, default 127.0.0.1:18443
EDGE_RUNTIME_TLS_CERTIFICATEedgeBootstrap listener certificate path
EDGE_RUNTIME_TLS_PRIVATE_KEYedgeBootstrap listener key path

Edge control and identity

VariableRequiredMeaning and default
EDGE_CONTROL_URLedge agentPublic mutual-TLS control URL
EDGE_CONTROL_BINDcontrolListener publication, default 0.0.0.0:8443
EDGE_CONTROL_SERVER_CERTIFICATEcontrolEdge-control server certificate path
EDGE_CONTROL_SERVER_PRIVATE_KEYcontrolEdge-control private key path
EDGE_CONTROL_CA_CERTIFICATEedge agentServer trust anchor
EDGE_IDENTITY_CA_CERTIFICATEcontrol/edge-controlClient identity CA certificate
EDGE_IDENTITY_CA_PRIVATE_KEYcoreRestricted worker-readable CA key
EDGE_IDENTITY_CA_PRIVATE_KEY_PASSPHRASEoptional coreCA-key passphrase
EDGE_STATUS_TOKENedge hostSeparate agent-to-cell control token
EDGE_IDfirst enrollmentAdministrator-created edge UUID
EDGE_BOOTSTRAP_TOKENfirst enrollmentOne-time secret; remove after registration

The edge-agent binary also accepts these internal variables:

VariableDefaultPurpose
EDGE_STATE_DIR/var/lib/cdnfoundry/agentPersistent identity, state, controls, acknowledgements
EDGE_RUNTIME_DIRemptyActive and previous compiled runtime directories
EDGE_CELL_STATUS_URLSemptyComma-separated internal cell endpoints
EDGE_CELL_ASSIGNMENTS{}JSON object mapping at most 32 stable cell-NN names to a pool name or an empty unassigned value
EDGE_RUNTIME_VERSIONS{}JSON object containing the four immutable gateway, agent, normal-cell, and WAF-cell image digests reported after a fixed installer upgrade
EDGE_ONCEfalseRun one sync cycle for diagnostics

Production fixes EDGE_CELL_ASSIGNMENTS to eight stable slots. The OpenResty container receives EDGE_CELL_NAME, EDGE_RUNTIME_FILE, and EDGE_STATUS_TOKEN from Compose. These describe a cell and are not customer settings.

Development-only environment

.env.dev supports:

VariablePurpose
CDNF_DEV_EDGE_A_ID, CDNF_DEV_EDGE_B_IDCreated edge UUIDs
CDNF_DEV_EDGE_A_BOOTSTRAP_TOKEN, CDNF_DEV_EDGE_B_BOOTSTRAP_TOKENOne-time tokens
CDNF_DEV_EDGE_STATUS_TOKENShared development agent/cell token
CDNF_DEV_EDGE_CONTROL_BINDOptional host override for port 9443
POWERADMIN_ADMIN_USERNAMEPowerAdmin diagnostic login; default admin
POWERADMIN_ADMIN_PASSWORDPowerAdmin diagnostic password; development-only default

The development Compose file contains public test credentials. Never copy them to production.

Documentation build

VariableDefaultPurpose
DOCS_SITE_URLhttps://vaheed.github.io/CDNFoundryCanonical and sitemap origin
DOCS_BASE/CDNFoundry/VitePress deployment base path

Set both when deploying the static site under a different origin or path.

Laravel framework variables

The application retains conventional Laravel configuration keys in core/config/: APP_NAME, APP_ENV, APP_KEY, APP_DEBUG, APP_URL, APP_LOCALE, APP_FALLBACK_LOCALE, APP_FAKER_LOCALE, APP_PREVIOUS_KEYS, APP_MAINTENANCE_DRIVER, and APP_MAINTENANCE_STORE.

Database drivers additionally accept DB_CONNECTION, DB_URL, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_SOCKET, DB_CHARSET, DB_COLLATION, DB_FOREIGN_KEYS, DB_ENCRYPT, DB_TRUST_SERVER_CERTIFICATE, DB_CONNECT_TIMEOUT, MYSQL_ATTR_SSL_CA, and the documented DB_SSLMODE.

Cache, queue, Redis, and session drivers accept their standard keys: CACHE_STORE, CACHE_PREFIX, DB_CACHE_CONNECTION, DB_CACHE_TABLE, DB_CACHE_LOCK_CONNECTION, DB_CACHE_LOCK_TABLE, DYNAMODB_CACHE_TABLE, DYNAMODB_ENDPOINT, MEMCACHED_HOST, MEMCACHED_PORT, MEMCACHED_USERNAME, MEMCACHED_PASSWORD, MEMCACHED_PERSISTENT_ID, QUEUE_CONNECTION, QUEUE_FAILED_DRIVER, DB_QUEUE_CONNECTION, DB_QUEUE_TABLE, DB_QUEUE, DB_QUEUE_RETRY_AFTER, BEANSTALKD_QUEUE_HOST, BEANSTALKD_QUEUE, BEANSTALKD_QUEUE_RETRY_AFTER, SQS_PREFIX, SQS_QUEUE, SQS_SUFFIX, REDIS_CLIENT, REDIS_URL, REDIS_HOST, REDIS_USERNAME, REDIS_PASSWORD, REDIS_PORT, REDIS_DB, REDIS_CACHE_DB, REDIS_PREFIX, REDIS_PERSISTENT, REDIS_CLUSTER, REDIS_MAX_RETRIES, REDIS_BACKOFF_ALGORITHM, REDIS_BACKOFF_BASE, REDIS_BACKOFF_CAP, REDIS_CONNECT_TIMEOUT, REDIS_READ_TIMEOUT, REDIS_QUEUE_CONNECTION, REDIS_QUEUE, REDIS_QUEUE_RETRY_AFTER, REDIS_CACHE_CONNECTION, REDIS_CACHE_LOCK_CONNECTION, SESSION_DRIVER, SESSION_LIFETIME, SESSION_EXPIRE_ON_CLOSE, SESSION_ENCRYPT, SESSION_PATH, SESSION_DOMAIN, SESSION_SECURE_COOKIE, SESSION_HTTP_ONLY, SESSION_SAME_SITE, SESSION_PARTITIONED_COOKIE, SESSION_CONNECTION, SESSION_TABLE, and SESSION_STORE.

Mail/logging/storage/auth integrations retain the keys declared in their Laravel config files: FILESYSTEM_DISK, CACHE_STORAGE_DISK, CACHE_STORAGE_PATH, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION, AWS_BUCKET, AWS_URL, AWS_ENDPOINT, AWS_USE_PATH_STYLE_ENDPOINT, MAIL_MAILER, MAIL_URL, MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_SCHEME, MAIL_SENDMAIL_PATH, MAIL_EHLO_DOMAIN, MAIL_FROM_ADDRESS, MAIL_FROM_NAME, MAIL_LOG_CHANNEL, POSTMARK_API_KEY, POSTMARK_MESSAGE_STREAM_ID, RESEND_API_KEY, SLACK_BOT_USER_OAUTH_TOKEN, SLACK_BOT_USER_DEFAULT_CHANNEL, LOG_CHANNEL, LOG_STACK, LOG_LEVEL, LOG_DAILY_DAYS, LOG_DEPRECATIONS_CHANNEL, LOG_DEPRECATIONS_TRACE, LOG_STDERR_FORMATTER, LOG_SYSLOG_FACILITY, PAPERTRAIL_URL, PAPERTRAIL_PORT, LOG_PAPERTRAIL_HANDLER, LOG_SLACK_WEBHOOK_URL, LOG_SLACK_USERNAME, LOG_SLACK_EMOJI, AUTH_GUARD, AUTH_MODEL, AUTH_PASSWORD_BROKER, AUTH_PASSWORD_RESET_TOKEN_TABLE, AUTH_PASSWORD_TIMEOUT, SANCTUM_STATEFUL_DOMAINS, and SANCTUM_TOKEN_PREFIX.

Horizon accepts HORIZON_NAME, HORIZON_DOMAIN, and HORIZON_PATH. Production Compose intentionally fixes the supported drivers and does not expose most framework alternatives in .env.prod.example.

CDNFoundry documentation