Environment Reference
How environment files work
Each backend package uses dotenv-flow. The NODE_ENV value determines which file is loaded:
| File | Purpose | Gitignored |
|---|---|---|
.env.development | Dev server (bun run server:dev) | Typically no |
.env.local | Personal overrides | Yes |
.env.test | Test suite (bun run test) | Usually |
To set up a new package, copy from an existing working package and adjust ports / service name / Snowflake ID.
Each package's npm scripts pass the env file explicitly:
json
"server:dev": "NODE_ENV=development bun run start --env-file=.env.development"Common Variables (All Services)
These are shared across every backend service.
Application
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_APPLICATION_NAME | Yes | Service name (used in logging, service discovery) | identity |
APP_ENV_APPLICATION_CODE | Yes | Unique service code | SVC-00010-IDENTITY |
APP_ENV_APPLICATION_ROLES | Yes | Service role tag | identity |
APP_ENV_APPLICATION_TIMEZONE | Yes | Timezone | Asia/Ho_Chi_Minh |
APP_ENV_APPLICATION_SECRET | Yes | Shared secret for AES-256-GCM payload encryption (certificate system, credential encryption). Must be identical across all services. | — |
APP_ENV_APPLICATION_DS_MIGRATION | No | Migration datasource name | pg_core |
APP_ENV_APPLICATION_DS_AUTHORIZE | No | Authorization datasource name | pg_core |
Server
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_SERVER_HOST | Yes | Bind host | localhost |
APP_ENV_SERVER_PORT | Yes | Bind port (unique per service) | 31010 |
APP_ENV_SERVER_BASE_PATH | Yes | API base path | /v1/api/identity |
Snowflake ID
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_SNOWFLAKE_WORKER_ID | Yes | Unique worker ID (0-1023). Must be unique per running instance — collisions cause duplicate IDs. | 1 |
APP_ENV_SNOWFLAKE_EPOCH_CHECKPOINT | Yes | Epoch start (ms since Unix epoch) | 1735689600000 |
PostgreSQL
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_POSTGRES_HOST | Yes | Database host | localhost |
APP_ENV_POSTGRES_PORT | Yes | Database port | 5432 |
APP_ENV_POSTGRES_DATABASE | Yes | Database name | nx_seller |
APP_ENV_POSTGRES_USERNAME | Yes | DB user | postgres |
APP_ENV_POSTGRES_PASSWORD | Yes | DB password | — |
Redis (Cache)
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_CACHE_REDIS_MODE | Yes | single or cluster | cluster |
APP_ENV_CACHE_REDIS_IDENTIFIER | Yes | Logical name | cache |
APP_ENV_CACHE_REDIS_PASSWORD | No | Redis password | — |
APP_ENV_CACHE_REDIS_HOST | Single mode | Redis host | localhost |
APP_ENV_CACHE_REDIS_PORT | Single mode | Redis port | 6379 |
APP_ENV_CACHE_REDIS_CLUSTER_NODES | Cluster mode | Comma-separated host:port | node1:6379,node2:6380 |
Redis (BullMQ / Queues)
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_BULLMQ_REDIS_HOST | If using queues | Redis host for BullMQ | localhost |
APP_ENV_BULLMQ_REDIS_PORT | If using queues | Redis port | 6379 |
APP_ENV_BULLMQ_REDIS_PASSWORD | No | Redis password | — |
External Services
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_IDENTITY_SERVICE_BASE_URL | Yes (all verifiers) | Identity service URL for JWKS | http://localhost:31010/v1/api/identity |
APP_ENV_JWKS_REST_PATH | No | JWKS endpoint path | /jw-certs (default) |
APP_ENV_BASIC_AUTH_USERNAME | No | HTTP Basic auth user | superadmin |
APP_ENV_BASIC_AUTH_PASSWORD | No | HTTP Basic auth password | — |
Logging
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_LOGGER_FOLDER_PATH | No | Log file output directory | ./app_data/logs |
APP_ENV_PARSE_RESULT_FOLDER_PATH | No | Parse result output | ./app_data/parse_result |
Misc
| Variable | Description | Example |
|---|---|---|
DEBUG | Enable debug output | true |
NODE_ENV | Runtime environment | development |
RUN_MODE | startup or migrate | startup |
TZ | System timezone | Asia/Ho_Chi_Minh |
Identity Service Only (JWKS Issuer)
These variables are only needed by @nx/identity — the JWKS issuer.
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_JWT_EXPIRES_IN | Yes | JWT lifetime in seconds | 86400 (1 day) |
APP_ENV_JWKS_ALGORITHM | Yes | Signing algorithm | ES256 |
APP_ENV_JWKS_PRIVATE_KEY | Yes | ECDSA private key (PEM, PKCS#8 format) | -----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY----- |
APP_ENV_JWKS_PUBLIC_KEY | Yes | ECDSA public key (PEM) | -----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY----- |
PKCS#8 required
The private key must use PKCS#8 format (-----BEGIN PRIVATE KEY-----), not SEC1 (-----BEGIN EC PRIVATE KEY-----). Generate with:
bash
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
| tee private.pem | openssl pkey -pubout > public.pemLicensing Service
| Variable | Required | Description | Default |
|---|---|---|---|
APP_ENV_LICENSING_ED25519_PRIVATE_KEY | No* | Ed25519 PEM private key for certificate signing | — |
APP_ENV_LICENSING_ED25519_PUBLIC_KEY | No* | Ed25519 PEM public key for verification | — |
APP_ENV_LICENSING_CERT_TTL_SECONDS | No | Certificate TTL (written to Redis + payload) | 86400 |
* If missing, publishCertificate() silently skips — licenses are issued but without certificates.
Signal Service (WebSocket)
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_WEBSOCKET_REDIS_MODE | Yes | single or cluster | single |
APP_ENV_WEBSOCKET_REDIS_HOST | Single mode | WebSocket Redis host | localhost |
APP_ENV_WEBSOCKET_REDIS_PORT | Single mode | WebSocket Redis port | 6379 |
APP_ENV_WEBSOCKET_ECDH_INFO | Yes | HKDF info string for E2E encryption | — |
Asset Service (S3 / MinIO)
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_MINIO_HOST | Yes | S3-compatible storage host | localhost |
APP_ENV_MINIO_API_PORT | Yes | S3 API port | 9000 |
APP_ENV_MINIO_ACCESS_KEY | Yes | S3 access key | — |
APP_ENV_MINIO_SECRET_KEY | Yes | S3 secret key | — |
Search Service (Typesense)
| Variable | Required | Description | Example |
|---|---|---|---|
APP_ENV_TYPESENSE_API_KEY | Yes | Typesense API key | — |
APP_ENV_TYPESENSE_NODES | Yes | Node list (protocol:host:port) | http:localhost:8108 |
Commerce / Cross-Service URLs
| Variable | Purpose | Example |
|---|---|---|
APP_ENV_COMMERCE_SERVICE_BASE_URL | Commerce API base for cross-service calls | http://localhost:31020/v1/api/commerce |
Payment Service
| Variable | Description |
|---|---|
APP_ENV_MQ_PAY_MODE | Deployment mode: full (default), api (REST only), worker (BullMQ only) |
Service Registry Quick Reference
| Service | APPLICATION_NAME | APPLICATION_CODE | SERVER_PORT | SNOWFLAKE_WORKER_ID | SERVER_BASE_PATH |
|---|---|---|---|---|---|
| identity | identity | SVC-00010-IDENTITY | 31010 | 1 | /v1/api/identity |
| commerce | commerce | SVC-00020-COMMERCE | 31020 | 2 | /v1/api/commerce |
| sale | sale | SVC-00030-SALE | 31030 | 3 | /v1/api/sale |
| finance | finance | SVC-00040-FINANCE | 31040 | 4 | /v1/api/finance |
| inventory | inventory | SVC-00050-INVENTORY | 31050 | 5 | /v1/api/inventory |
| ledger | ledger | SVC-00060-LEDGER | 31060 | 6 | /v1/api/ledger |
| pricing | pricing | SVC-00070-PRICING | 31070 | 7 | /v1/api/pricing |
| payment | payment | SVC-00080-PAYMENT | 31080 | 8 | /v1/api/payment |
| signal | signal | SVC-00090-SIGNAL | 31090 | 9 | /v1/api/signal |
| outreach | outreach | SVC-00110-OUTREACH | 31110 | 10 | /v1/api/outreach |
| licensing | licensing | SVC-00140-LICENSING | 31120 | 11 | /v1/api/licensing |
| taxation | taxation | SVC-00130-TAXATION | 31130 | 13 | /v1/api/taxation |
Related Pages
| Page | Description |
|---|---|
| Getting Started | Setup walkthrough |
| Build System | Make targets |
| IGNIS Patterns | Framework configuration patterns |
| Licensing — Certificates | How APP_ENV_APPLICATION_SECRET is used for certificate encryption |