Skip to content

Environment Variables Reference

Complete reference of all environment variables used by the IGNIS framework, grouped by category with defaults and required/optional status.

Files:

Overview

IGNIS uses the APP_ENV_ prefix for all framework-specific environment variables. This prevents conflicts with system variables like PATH, HOME, etc.

bash
# ✅ IGNIS variables
APP_ENV_POSTGRES_HOST=localhost

# ❌ Might conflict with system
POSTGRES_HOST=localhost

Accessing Environment Variables

typescript
// Direct access
const host = process.env.APP_ENV_POSTGRES_HOST;

// Using applicationEnvironment helper (recommended)
import { applicationEnvironment } from '@venizia/ignis-helpers';
import { EnvironmentKeys } from '@venizia/ignis';
const host = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_POSTGRES_HOST);

Quick Start Template

Create a .env file in your project root:

bash
# .env

# ----------------------
# APPLICATION
# ----------------------
APP_ENV_APPLICATION_NAME=my-app
APP_ENV_APPLICATION_TIMEZONE=UTC

# ----------------------
# SERVER
# ----------------------
APP_ENV_SERVER_HOST=0.0.0.0
APP_ENV_SERVER_PORT=3000
APP_ENV_SERVER_BASE_PATH=/api

# ----------------------
# DATABASE (PostgreSQL)
# ----------------------
APP_ENV_POSTGRES_HOST=localhost
APP_ENV_POSTGRES_PORT=5432
APP_ENV_POSTGRES_USERNAME=postgres
APP_ENV_POSTGRES_PASSWORD=your_password_here
APP_ENV_POSTGRES_DATABASE=my_database

# ----------------------
# AUTHENTICATION
# ----------------------
APP_ENV_APPLICATION_SECRET=generate-a-strong-random-secret
APP_ENV_JWT_SECRET=generate-another-strong-random-secret
APP_ENV_JWT_EXPIRES_IN=86400

# ----------------------
# LOGGING
# ----------------------
APP_ENV_LOGGER_FOLDER_PATH=./logs

Important: Add .env to your .gitignore to prevent committing secrets.

Application Variables

VariableRequiredDefaultDescription
APP_ENV_APPLICATION_NAMENoAPPApplication name, used in logs and identification
APP_ENV_APPLICATION_TIMEZONENoAsia/Ho_Chi_MinhDefault timezone for date operations
APP_ENV_APPLICATION_ROLESNo-Comma-separated list of application roles

Example

bash
APP_ENV_APPLICATION_NAME=ignis-backend
APP_ENV_APPLICATION_TIMEZONE=UTC
APP_ENV_APPLICATION_ROLES=api,worker

Server Variables

VariableRequiredDefaultDescription
APP_ENV_SERVER_HOSTNolocalhostServer bind address
APP_ENV_SERVER_PORTNo3000Server port
APP_ENV_SERVER_BASE_PATHNo-Base path convention (EnvironmentKeys constant; not read by the framework itself)
HOSTNo-Alternative to APP_ENV_SERVER_HOST (takes precedence)
PORTNo-Alternative to APP_ENV_SERVER_PORT (takes precedence)

Example

bash
# Development
APP_ENV_SERVER_HOST=localhost
APP_ENV_SERVER_PORT=3000
APP_ENV_SERVER_BASE_PATH=/api

# Production
APP_ENV_SERVER_HOST=0.0.0.0
APP_ENV_SERVER_PORT=8080
APP_ENV_SERVER_BASE_PATH=/v1/api

Priority Order

The server host/port resolution uses this priority (packages/kernel/src/base/applications/abstract.ts):

  1. Explicit config passed to the application constructor
  2. HOST/PORT variables (for cloud platforms)
  3. APP_ENV_SERVER_HOST/APP_ENV_SERVER_PORT variables
  4. Default values (localhost/3000)

Database Variables (PostgreSQL)

VariableRequiredDefaultDescription
APP_ENV_POSTGRES_HOSTYes*localhostDatabase host
APP_ENV_POSTGRES_PORTNo5432Database port
APP_ENV_POSTGRES_USERNAMEYes*postgresDatabase username
APP_ENV_POSTGRES_PASSWORDYes*-Database password
APP_ENV_POSTGRES_DATABASEYes*-Database name
APP_ENV_DATASOURCE_NAMENo-DataSource identifier

*Required when using PostgreSQL DataSource.

Example

bash
# Local development
APP_ENV_POSTGRES_HOST=localhost
APP_ENV_POSTGRES_PORT=5432
APP_ENV_POSTGRES_USERNAME=postgres
APP_ENV_POSTGRES_PASSWORD=password
APP_ENV_POSTGRES_DATABASE=my_app_dev

# Production
APP_ENV_POSTGRES_HOST=db.example.com
APP_ENV_POSTGRES_PORT=5432
APP_ENV_POSTGRES_USERNAME=app_user
APP_ENV_POSTGRES_PASSWORD=strong_password_here
APP_ENV_POSTGRES_DATABASE=my_app_prod

DataSource Configuration

typescript
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';

@datasource({ driver: NodePostgresDriver })
export class PostgresDataSource extends BaseDataSource {
  constructor() {
    super({
      name: PostgresDataSource.name,
      config: {
        host: process.env.APP_ENV_POSTGRES_HOST ?? 'localhost',
        port: +(process.env.APP_ENV_POSTGRES_PORT ?? 5432),
        database: process.env.APP_ENV_POSTGRES_DATABASE ?? 'mydb',
        user: process.env.APP_ENV_POSTGRES_USERNAME ?? 'postgres',
        password: process.env.APP_ENV_POSTGRES_PASSWORD ?? '',
      },
    });
  }
}

Authentication Variables

VariableRequiredDefaultDescription
APP_ENV_APPLICATION_SECRETYes*-Secret for encrypting JWT payload
APP_ENV_JWT_SECRETYes*-Secret for signing JWT tokens
APP_ENV_JWT_EXPIRES_INNo-Token expiration in seconds (e.g., 86400 = 24h)

*Required by convention when using the authentication component - see below.

Security Requirements

  • Not read directly. The AuthenticateComponent receives its secrets programmatically via the jwtOptions binding (jwtSecret, getTokenExpiresFn) - it never reads these environment variables itself.
  • EnvironmentKeys is the convention, not a requirement. These constants are the conventional way for your application to supply those values into the binding.
  • A missing or placeholder secret fails the boot. The component throws at startup if jwtSecret is missing or left at the placeholder value. Wiring it from an unset environment variable fails the same way.

Generate Strong Secrets

bash
# Generate random secrets
openssl rand -base64 32  # For APP_ENV_APPLICATION_SECRET
openssl rand -base64 32  # For APP_ENV_JWT_SECRET

Example

bash
APP_ENV_APPLICATION_SECRET=K8sX2mP9qR4tV7wZ1aD3fG6hJ9kL2nO5
APP_ENV_JWT_SECRET=M3nB6vC9xZ2aS5dF8gH1jK4lP7oI0uY
APP_ENV_JWT_EXPIRES_IN=86400

Common Expiration Values

ValueDuration
36001 hour
8640024 hours (1 day)
6048007 days
259200030 days

Logging Variables

VariableRequiredDefaultDescription
APP_ENV_LOGGER_FOLDER_PATHNo(unset)Directory for log files; file logging is OFF when unset
APP_ENV_LOGGER_FORMATNotextLog output format
APP_ENV_LOGGER_LEVELNodebugLogger-level floor; transports without their own level inherit it
APP_ENV_LOGGER_INSPECT_DEPTHNo5How deep a %s argument is inspected. Node hard-codes depth 0 for %s, which prints [Object] one level in; IGNIS widens it. Non-negative integers only - an absent, invalid or negative value falls back to 5
APP_ENV_LOGGER_DO_REDACTNotrueSecret redaction in logged values. ONLY the literal false disables it (reveals raw credentials in log lines); anything else keeps redaction ON. Never disable in production
APP_ENV_LOGGER_COLORNo(unset)ANSI color on console log lines. Unset means auto: ON in a development NODE_ENV, OFF in production, staging, uat and any unrecognized name. NO_COLOR also turns it off
APP_ENV_LOGGER_FILE_FREQUENCYNo1hLog file rotation frequency
APP_ENV_LOGGER_FILE_MAX_SIZENo100mMax size per log file
APP_ENV_LOGGER_FILE_MAX_FILESNo5dLog file retention
APP_ENV_LOGGER_FILE_DATE_PATTERNNoYYYYMMDD_HHRotated file date pattern
APP_ENV_LOGGER_DGRAM_HOSTNo-UDP log transport host
APP_ENV_LOGGER_DGRAM_PORTNo-UDP log transport port
APP_ENV_LOGGER_DGRAM_LABELNo-Label for UDP logs
APP_ENV_LOGGER_DGRAM_LEVELSNo-Comma-separated log levels for UDP
APP_ENV_EXTRA_LOG_ENVSNo-Extra env vars to include in logs

Example

bash
# File logging
APP_ENV_LOGGER_FOLDER_PATH=./app_data/logs

# UDP logging (for log aggregators)
APP_ENV_LOGGER_DGRAM_HOST=127.0.0.1
APP_ENV_LOGGER_DGRAM_PORT=5000
APP_ENV_LOGGER_DGRAM_LABEL=my-app
APP_ENV_LOGGER_DGRAM_LEVELS=error,warn,info

Storage Variables (MinIO/S3)

NOTE

These are application-level conventions (used by the vert reference application), not variables read by the framework. MinioHelper and the StaticAsset component receive their configuration programmatically - your application wires these values in.

VariableRequiredDefaultDescription
APP_ENV_MINIO_HOSTYes*-MinIO/S3 endpoint
APP_ENV_MINIO_API_PORTNo9000MinIO API port
APP_ENV_MINIO_ACCESS_KEYYes*-Access key
APP_ENV_MINIO_SECRET_KEYYes*-Secret key
APP_ENV_MINIO_USE_SSLNofalseEnable SSL

*Required (by application convention) when wiring MinIO-backed storage.

Example

bash
# Local MinIO
APP_ENV_MINIO_HOST=localhost
APP_ENV_MINIO_API_PORT=9000
APP_ENV_MINIO_ACCESS_KEY=minioadmin
APP_ENV_MINIO_SECRET_KEY=minioadmin
APP_ENV_MINIO_USE_SSL=false

# AWS S3
APP_ENV_MINIO_HOST=s3.amazonaws.com
APP_ENV_MINIO_API_PORT=443
APP_ENV_MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
APP_ENV_MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
APP_ENV_MINIO_USE_SSL=true

Mail Variables

NOTE

These are application-level conventions, not variables read by the framework. The Mail component's transporter receives its SMTP/OAuth2 configuration programmatically - your application wires these values in.

VariableRequiredDefaultDescription
APP_ENV_MAIL_HOSTYes*-SMTP host (e.g., smtp.gmail.com)
APP_ENV_MAIL_PORTNo-SMTP port (e.g., 465)
APP_ENV_MAIL_SECURENo-Use TLS
APP_ENV_MAIL_USERYes*-SMTP username/email
APP_ENV_MAIL_CLIENT_IDYes*-OAuth2 client ID
APP_ENV_MAIL_CLIENT_SECRETYes*-OAuth2 client secret
APP_ENV_MAIL_REFRESH_TOKENYes*-OAuth2 refresh token

*Required (by application convention) when wiring the Mail component with OAuth2.

Example (Gmail with OAuth2)

bash
APP_ENV_MAIL_HOST=smtp.gmail.com
APP_ENV_MAIL_PORT=465
APP_ENV_MAIL_SECURE=true
APP_ENV_MAIL_USER=your-email@gmail.com
APP_ENV_MAIL_CLIENT_ID=your-oauth2-client-id
APP_ENV_MAIL_CLIENT_SECRET=your-oauth2-client-secret
APP_ENV_MAIL_REFRESH_TOKEN=your-oauth2-refresh-token

DataSource Variables

VariableRequiredDefaultDescription
APP_ENV_DS_MIGRATIONNopostgresDataSource name for migrations. Read at boot and printed in the startup banner
APP_ENV_DS_AUTHORIZENopostgresDataSource name for authorization. Read at boot and printed in the startup banner
APP_ENV_AUTO_PROVISION_COLLECTIONNofalseLets a search datasource create a missing collection on first use. true or 1 enables it; the autoProvision constructor option overrides it

These two name the datasource, they do not select it

APP_ENV_DS_MIGRATION and APP_ENV_DS_AUTHORIZE reach the startup banner and nothing else - the framework does not resolve a datasource from either. Wire your own lookup if you need one.

Environments (packages/core-server/src/common/environments.ts) also declares APP_ENV_APPLICATION_DS_MIGRATION, APP_ENV_APPLICATION_DS_AUTHORIZE and APP_ENV_APPLICATION_DS_OAUTH2. Those are name constants with no reader anywhere in the framework - setting them changes nothing.

Debug Variables

VariableRequiredDefaultDescription
DEBUGNo-Enable debug mode
NODE_ENVNodevelopmentEnvironment mode. One of local, debug, development, dev, sit, uat, alpha, beta, staging, production
ALLOW_EMPTY_ENV_VALUENofalseAllow empty env values
RUN_MODENo-Printed in the startup banner. The framework never branches on it - read it yourself to split a migrate run from a serve run
  • Fail-closed by default. An environment IGNIS does not recognize is treated as production, so error responses are sanitized.
  • Development environments expose error detail. local, debug, development, dev, and sit are the development set - only these show internal error detail.
  • Everything else stays sanitized. alpha, beta, staging, and production never expose internal detail, matching production behavior.

Example

bash
# Development - `dev` is an alias of `development`, and gets the same error detail
NODE_ENV=dev
DEBUG=true

# Production
NODE_ENV=production

Secrets & Vault

  • A .env file is one option, not a requirement. IGNIS can load these variables from a vault (HashiCorp Vault, an encrypted .env.vault, or plain process.env). It hydrates them into the same APP_ENV_* keys at boot.
  • Hydration is transparent to your code. Code that reads process.env.APP_ENV_* keeps working unchanged - the values arrive from the vault instead of a file.
  • Hydration runs before datasources are configured (after preConfigure(), before registerDataSources()), so a hydrated APP_ENV_DS_PASSWORD is available exactly where a file-based one would be.
  • Vault values take precedence over process.env when the provider is live - a hydrated key overwrites whatever was already in process.env.
typescript
// Store the key in the vault already named APP_ENV_... and it merges as-is.
override registerSecrets() {
  return {
    provider: SecretProviders.HASHICORP_VAULT,
    config: { endpoint, auth: { method: VaultAuthMethods.APP_ROLE, roleId, secretId } },
    hydrate: [{ path: 'secret/data/myapp/config' }],
  };
}

Failure policy

If the vault is unreachable, development environments (local, debug, development, dev, sit) fall back to process.env. Every other environment fails the boot rather than starting with missing secrets.

See the Secrets & Vault guide for setup and the Secrets & Vault reference for the full API.

Environment-Specific Files

Create environment-specific .env files:

project/
├── .env                 # Default (development)
├── .env.local           # Local overrides (gitignored)
├── .env.production      # Production values
├── .env.test            # Test environment
└── .env.example         # Template for team (committed)

Loading Priority

  1. .env.local (highest priority, gitignored)
  2. .env.{NODE_ENV} (e.g., .env.production)
  3. .env (default)

Custom Environment Prefix

You can customize the prefix from APP_ENV to something else via the APPLICATION_ENV_PREFIX variable. It is read once when @venizia/ignis-helpers loads, so set it in the shell (or before any framework import):

bash
# Set custom prefix
APPLICATION_ENV_PREFIX=MY_APP

# Now use MY_APP_ prefix
MY_APP_POSTGRES_HOST=localhost

Validation

On startup, IGNIS iterates every APP_ENV_* (prefixed) variable that is set and throws if any has an empty value (validateEnvs in packages/kernel/src/base/applications/abstract.ts). It does not check for variables that are absent entirely - component-level validation (e.g., the authentication component's jwtSecret check) covers required values.

Disable Validation

bash
# Allow empty env values (not recommended for production)
ALLOW_EMPTY_ENV_VALUE=true

Security Best Practices

  1. Never commit .env files - Add to .gitignore
  2. Use strong secrets - Generate with openssl rand -base64 32
  3. Rotate secrets regularly - Especially JWT_SECRET
  4. Use different values per environment - Don't reuse dev secrets in production
  5. Use secret managers in production - AWS Secrets Manager, HashiCorp Vault, etc.

Complete .env.example

bash
# ----------------------
# IGNIS ENVIRONMENT VARIABLES
# ----------------------
# Copy this file to .env and fill in values

# APPLICATION
APP_ENV_APPLICATION_NAME=my-app
APP_ENV_APPLICATION_TIMEZONE=UTC

# SERVER
APP_ENV_SERVER_HOST=0.0.0.0
APP_ENV_SERVER_PORT=3000
APP_ENV_SERVER_BASE_PATH=/api

# DATABASE
APP_ENV_POSTGRES_HOST=localhost
APP_ENV_POSTGRES_PORT=5432
APP_ENV_POSTGRES_USERNAME=postgres
APP_ENV_POSTGRES_PASSWORD=
APP_ENV_POSTGRES_DATABASE=

# AUTHENTICATION (Required for auth component)
APP_ENV_APPLICATION_SECRET=
APP_ENV_JWT_SECRET=
APP_ENV_JWT_EXPIRES_IN=86400

# LOGGING
APP_ENV_LOGGER_FOLDER_PATH=./logs

# STORAGE (Optional - MinIO/S3)
# APP_ENV_MINIO_HOST=localhost
# APP_ENV_MINIO_API_PORT=9000
# APP_ENV_MINIO_ACCESS_KEY=
# APP_ENV_MINIO_SECRET_KEY=
# APP_ENV_MINIO_USE_SSL=false

# MAIL (Optional)
# APP_ENV_MAIL_HOST=smtp.gmail.com
# APP_ENV_MAIL_PORT=465
# APP_ENV_MAIL_USER=
# APP_ENV_MAIL_CLIENT_ID=
# APP_ENV_MAIL_CLIENT_SECRET=
# APP_ENV_MAIL_REFRESH_TOKEN=

See also