Skip to main content

Environment Variables

Complete reference for all configuration options in BFFless.

Quick Reference

VariableRequiredDefaultDescription
ENCRYPTION_KEYYes-AES-256 key for encrypting storage credentials
POSTGRES_PASSWORDYeschangemePostgreSQL password
PRIMARY_DOMAINYeslocalhostMain domain for the platform
FRONTEND_URLYeshttp://localhostURL users access the application
JWT_SECRETNoAuto-generatedJWT signing secret
API_KEY_SALTNoAuto-generatedSalt for hashing API keys
STORAGE_TYPENominioStorage backend type
COOKIE_SECURENofalseUse HTTPS-only cookies

Security Keys

ENCRYPTION_KEY

  • Required: Yes
  • Example: Generate with openssl rand -base64 32
  • Description: AES-256 key for encrypting storage credentials in the database
warning

This key MUST be set before first run and NEVER changed afterward. If lost or changed, you'll need to reconfigure all storage settings.

# Generate and set
echo "ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .env

JWT_SECRET

  • Required: No (auto-generated during setup)
  • Example: Generate with openssl rand -base64 32
  • Description: Secret for signing JWT authentication tokens

Set manually only for multi-instance deployments sharing the same database.

API_KEY_SALT

  • Required: No (auto-generated during setup)
  • Example: Generate with openssl rand -base64 32
  • Description: Salt for hashing API keys before storage

Set manually only for multi-instance deployments sharing the same database.


Database Configuration

POSTGRES_PASSWORD

  • Required: Yes
  • Default: changeme
  • Description: PostgreSQL superuser password

Security: Always change from default in production!

DATABASE_URL

  • Required: No (auto-constructed)
  • Default: postgresql://postgres:{POSTGRES_PASSWORD}@postgres:5432/bffless
  • Description: Full PostgreSQL connection string

Override only if using an external database or custom configuration.


Domain & URL Configuration

PRIMARY_DOMAIN

  • Required: Yes
  • Default: localhost
  • Example: yourdomain.com
  • Description: Main domain for the platform

Used for:

  • Subdomain routing (www, admin, minio)
  • Nginx configuration
  • Wildcard SSL certificates
  • Dynamic domain routing

FRONTEND_URL

  • Required: Yes
  • Default: http://localhost
  • Example: https://www.yourdomain.com
  • Description: URL users use to access the application

Used for CORS, authentication cookies, and SuperTokens configuration.

API_DOMAIN

  • Required: No
  • Default: Same as FRONTEND_URL
  • Description: API server URL (only set if different from frontend)

In Docker/production with nginx, the API is proxied through the same domain, so this typically isn't needed.


  • Required: No
  • Default: false
  • Description: Require HTTPS for authentication cookies
EnvironmentValue
Local developmentfalse
Production with HTTPStrue
  • Required: Production only
  • Example: .yourdomain.com
  • Description: Cookie domain for cross-subdomain authentication

Use a leading dot to share cookies across all subdomains. Without this in production, authentication won't work across subdomains (e.g., logging in on admin.domain.com won't work on www.domain.com).


Authentication (SuperTokens)

SUPERTOKENS_CONNECTION_URI

  • Required: Yes (for Docker)
  • Default: http://supertokens:3567
  • Description: SuperTokens server URL
EnvironmentValue
Docker productionhttp://supertokens:3567
Local dev with Docker servicesEmpty (defaults to http://localhost:3567)
Managed servicehttps://your-app.supertokens.io

SUPERTOKENS_API_KEY

  • Required: No
  • Description: Optional API key for SuperTokens (adds extra security)

Not needed for self-hosted Docker instances.


Storage Configuration

STORAGE_TYPE

  • Required: No
  • Default: minio
  • Options: local, minio
  • Description: Storage backend for uploaded assets

See Storage Backends for detailed configuration.

MinIO Configuration

VariableDefaultDescription
MINIO_ROOT_USERminioadminMinIO admin username
MINIO_ROOT_PASSWORDchangemeMinIO admin password
MINIO_BUCKETassetsBucket name for assets
MINIO_ENDPOINTminioMinIO server hostname
MINIO_PORT9000MinIO API port
MINIO_ACCESS_KEYminioadminMinIO access key (usually same as ROOT_USER)
MINIO_SECRET_KEYchangemeMinIO secret key (usually same as ROOT_PASSWORD)
MINIO_USE_SSLfalseUse HTTPS for MinIO connections

Nginx & Reverse Proxy

BACKEND_HOST

  • Required: No
  • Default: backend
  • Description: Backend service hostname
EnvironmentValue
Dockerbackend (container name)
Local devlocalhost

BACKEND_PORT

  • Required: No
  • Default: 3000
  • Description: Backend API port

NGINX_SITES_PATH

  • Required: No
  • Default: /etc/nginx/sites-enabled
  • Description: Path where nginx site configs are written
EnvironmentValue
Docker/etc/nginx/sites-enabled
Local dev./nginx-dev/sites-enabled

NGINX_RELOAD_WAIT_MS

  • Required: No
  • Default: 3000
  • Description: Wait time (ms) for nginx file watcher to process config changes

SSL Certificates

SSL_CERT_PATH

  • Required: No
  • Default: /etc/nginx/ssl
  • Description: Directory for SSL certificates
EnvironmentValue
Docker/etc/nginx/ssl
Local dev./nginx-dev/ssl

CERTBOT_EMAIL

  • Required: Production only (for Let's Encrypt)
  • Example: admin@yourdomain.com
  • Description: Email for Let's Encrypt certificate notifications

CERTBOT_WEBROOT

  • Required: No
  • Default: /var/www/certbot
  • Description: Webroot directory for ACME HTTP-01 challenges

Email / SMTP

Optional configuration for sending emails (password resets, notifications). If not configured, emails are logged to console.

VariableDefaultDescription
SMTP_HOST-SMTP server hostname (e.g., smtp.gmail.com)
SMTP_PORT587SMTP port
SMTP_SECUREfalseUse TLS
SMTP_USER-SMTP username
SMTP_PASSWORD-SMTP password
EMAIL_FROM_NAMEBFFlessSender display name
EMAIL_FROM_ADDRESS-Sender email address

Generating Secrets

Generate all required secrets at once:

# Using OpenSSL
echo "ENCRYPTION_KEY=$(openssl rand -base64 32)"
echo "JWT_SECRET=$(openssl rand -base64 32)"
echo "API_KEY_SALT=$(openssl rand -base64 32)"
echo "POSTGRES_PASSWORD=$(openssl rand -base64 32)"
echo "MINIO_ROOT_PASSWORD=$(openssl rand -base64 32)"
echo "MINIO_SECRET_KEY=$(openssl rand -base64 32)"

Or using Node.js:

node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

Production Configuration Example

# Domain
PRIMARY_DOMAIN=yourdomain.com
FRONTEND_URL=https://www.yourdomain.com

# Security
COOKIE_SECURE=true
COOKIE_DOMAIN=.yourdomain.com

# SSL
CERTBOT_EMAIL=admin@yourdomain.com

# Secrets (generate unique values!)
ENCRYPTION_KEY=<generate-with-openssl>
POSTGRES_PASSWORD=<generate-with-openssl>
MINIO_ROOT_PASSWORD=<generate-with-openssl>
MINIO_SECRET_KEY=<generate-with-openssl>

Environment-Specific Defaults

Local Development

PRIMARY_DOMAIN=localhost
FRONTEND_URL=http://localhost
COOKIE_SECURE=false
STORAGE_TYPE=minio
MINIO_ENDPOINT=localhost

Docker Production

PRIMARY_DOMAIN=yourdomain.com
FRONTEND_URL=https://www.yourdomain.com
COOKIE_SECURE=true
COOKIE_DOMAIN=.yourdomain.com
SUPERTOKENS_CONNECTION_URI=http://supertokens:3567
MINIO_ENDPOINT=minio
BACKEND_HOST=backend