Environment Configuration Reference — Docker Compose and Helm
Environment Configuration — Docker Compose & Helm
Focused reference for configuring Fabrixly IDS and the Licensing Portal via .env (Docker Compose) or values.yaml (Helm). No setup steps — just the variables.
Fabrixly Identity Server
Docker Compose — .env file
Docker Compose reads from a .env file in the same directory as docker-compose.yml. Copy .env.example → .env and fill in your values.
fabrixly-identity-server/
├── docker-compose.yml
└── .env ← your config goes here
The compose file maps every variable via ${VAR_NAME} substitution. Variables with :-default have fallbacks; the rest must be set.
Required — must set
| Variable | Description |
|---|---|
SESSION_SECRET |
Session encryption key — min 32 chars. openssl rand -base64 32 |
JWT_SECRET |
JWT signing key — min 32 chars. openssl rand -base64 32 |
SMTP_HOST |
SMTP server (e.g. smtp.sendgrid.net) |
SMTP_USER |
SMTP username or API key |
SMTP_PASS |
SMTP password or API key |
SMTP_FROM |
Sender address e.g. "Fabrixly IDS" <no-reply@acme.com> |
Optional — have defaults
| Variable | Default | Description |
|---|---|---|
DB_USERNAME |
admin |
PostgreSQL username (used by both postgres & backend containers) |
DB_PASSWORD |
admin123 |
PostgreSQL password |
DB_NAME |
identity_server |
PostgreSQL database name |
DB_SYNC |
false |
Auto-sync DB schema on boot — keep false in production |
ISSUER |
https://ids.fabrixly.com/oidc |
Public OIDC issuer URL — change for production |
SMTP_PORT |
587 |
SMTP port |
SYSTEM_ADMIN_EMAIL |
admin@system.com |
Admin account email (seeded on first boot) |
SYSTEM_ADMIN_PASSWORD |
admin123 |
Admin account password (seeded on first boot) |
AUTO_SEED |
false |
Set true on first boot to seed admin + plans. Idempotent — safe to keep on. |
SELF_HOSTED |
false |
true = license key mode; plan selection hidden in console |
LICENSE_KEY |
(empty) | License JWT — required when SELF_HOSTED=true |
ENABLE_USER_REGISTRATION |
true |
Allow public self-registration |
Social login (optional — only if you enable a provider)
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID |
Google OAuth App client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth App client secret |
GITHUB_CLIENT_ID |
GitHub OAuth App client ID |
GITHUB_CLIENT_SECRET |
GitHub OAuth App client secret |
Minimal .env to get running
SESSION_SECRET=<openssl rand -base64 32>
JWT_SECRET=<openssl rand -base64 32>
SMTP_HOST=smtp.sendgrid.net
SMTP_USER=apikey
SMTP_PASS=SG.xxxx
SMTP_FROM="Fabrixly IDS" <no-reply@acme.com>
AUTO_SEED=true
Helm — values.yaml structure
The chart splits configuration into two blocks: env (plain config map) and secrets (Kubernetes Secret).
helm/fabrixly-ids/
├── values.yaml ← defaults (committed to git)
├── values-development.yaml ← dev overrides
├── values-secrets-development.yaml ← dev secrets (do NOT commit)
└── values-secrets-production.yaml ← prod secrets (do NOT commit)
backend.env — plain environment variables
Set these in your values override file. They become a ConfigMap in the pod.
backend:
env:
NODE_ENV: production
PORT: "3000"
ISSUER: "https://your-domain.com/oidc" # ← CHANGE
DB_HOST: "postgresql-service" # ← matches postgresql subchart service
DB_PORT: "5432"
DB_NAME: "identity_server"
DB_SYNC: "false"
DB_LOGGING: "false"
SMTP_HOST: "smtp.sendgrid.net"
SMTP_PORT: "587"
SMTP_SECURE: "true"
SMTP_FROM: "noreply@your-domain.com" # ← CHANGE
CONSOLE_URL: "https://your-domain.com" # ← CHANGE
AUTO_SEED: "true" # seed on first deploy, set false after
SYSTEM_ADMIN_EMAIL: "admin@system.com"
SELF_HOSTED: "false"
LICENSE_KEY: ""
ENABLE_USER_REGISTRATION: "true"
# Social login — uncomment to enable:
# GOOGLE_CLIENT_ID: ""
# GOOGLE_CLIENT_SECRET: ""
# GITHUB_CLIENT_ID: ""
# GITHUB_CLIENT_SECRET: ""
backend.secrets — injected as Kubernetes Secret
These become secretKeyRef env vars in the pod. Put them in a separate file that is NOT committed to git.
# values-secrets-production.yaml ← add to .gitignore!
backend:
secrets:
SESSION_SECRET: "..." # openssl rand -base64 32
JWT_SECRET: "..." # openssl rand -base64 32
DB_PASSWORD: "..." # postgres user password
SMTP_USER: "..." # smtp user / api key
SMTP_PASS: "..." # smtp password / api key
SYSTEM_ADMIN_PASSWORD: "..." # seeded admin password
postgresql:
auth:
password: "..." # must match backend.secrets.DB_PASSWORD
postgresPassword: "..." # postgres superuser password
backend.image — image & tag
backend:
image:
repository: kumaravinit/zero
tag: "ids-backend-1.0.1" # or "ids-backend-latest"
pullPolicy: IfNotPresent
console:
image:
repository: kumaravinit/zero
tag: "ids-console-1.0.1"
Install command
helm install fabrixly-ids ./helm/fabrixly-ids \
-f helm/fabrixly-ids/values.yaml \
-f helm/fabrixly-ids/values-production.yaml \
-f helm/fabrixly-ids/values-secrets-production.yaml \
--namespace fabrixly-ids --create-namespace
Licensing Portal
Docker Compose — .env file
zero-licencing-portal/
├── docker-compose.yml
└── .env ← your config goes here
The compose DB connection string is built automatically inside the file: DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
You do NOT need to set DATABASE_URL yourself when using compose.
Required — must set
| Variable | Description |
|---|---|
ISSUER |
IDS OIDC issuer URL — e.g. http://your-ids-host:3000/oidc |
CLIENT_SECRET |
OIDC client secret registered in IDS for this portal |
SESSION_SECRET |
Session key — openssl rand -base64 32 |
IDS_BASE_URL |
IDS API base URL (no /oidc) — e.g. http://your-ids-host:3000 |
IDS_ADMIN_PASSWORD |
IDS system admin password |
PRIVATE_KEY |
RSA private key (PKCS#8 PEM) for signing license JWTs |
Optional — have defaults
| Variable | Default | Description |
|---|---|---|
CLIENT_ID |
licensing-portal-client |
OIDC client ID registered in IDS |
REDIRECT_URI |
http://localhost:3005/callback |
OAuth callback URL — change for production |
DB_USERNAME |
admin |
Postgres username |
DB_PASSWORD |
admin123 |
Postgres password |
DB_NAME |
licensing_db |
Postgres database name (keep separate from IDS DB) |
IDS_ADMIN_EMAIL |
admin@system.com |
IDS admin email |
Note: The licensing portal postgres runs on host port5433(not5432) to avoid clashing with IDS postgres if both are on the same machine.
Generating PRIVATE_KEY
node -e "
const c = require('crypto');
const { privateKey } = c.generateKeyPairSync('rsa', {
modulusLength: 2048,
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
console.log(privateKey);
"
In .env, use single quotes to preserve newlines:
PRIVATE_KEY='-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAA...
-----END PRIVATE KEY-----'
Minimal .env to get running
ISSUER=https://ids.fabrixly.com/oidc
CLIENT_SECRET=licensing_portal_secret
SESSION_SECRET=<openssl rand -base64 32>
IDS_BASE_URL=https://ids.fabrixly.com
IDS_ADMIN_PASSWORD=admin123
PRIVATE_KEY='-----BEGIN PRIVATE KEY-----
<your key here>
-----END PRIVATE KEY-----'
Helm — values.yaml structure
zero-licencing-portal/helm/zero-licencing-portal/
└── values.yaml ← edit this (or pass an override file)
env — plain environment variables
env:
nodeEnv: production
port: 3005
issuer: "https://your-ids-domain.com/oidc" # ← CHANGE
clientId: "licensing-portal-client"
redirectUri: "https://licensing.your-domain.com/callback" # ← CHANGE
# Cluster-internal DNS to reach IDS backend
idsBaseUrl: "http://fabrixly-ids-backend.fabrixly-ids.svc.cluster.local:3000"
idsAdminEmail: "admin@system.com"
secrets — injected as Kubernetes Secret
secrets:
sessionSecret: "..." # openssl rand -base64 32
databaseUrl: "postgresql://admin:password@fabrixly-ids-postgresql.fabrixly-ids.svc.cluster.local:5432/licensing_db"
idsAdminPassword: "..." # IDS admin password
privateKey: | # full RSA PEM block
-----BEGIN PRIVATE KEY-----
MIIEvQIBADA...
-----END PRIVATE KEY-----
Important: ThedatabaseUrlin the Helm chart connects the portal to the IDS PostgreSQL pod using Kubernetes cluster DNS (fabrixly-ids-postgresql.fabrixly-ids.svc.cluster.local). The database name must be different from IDS (licensing_db). If you want fully isolated storage, point it to a separate PostgreSQL instance.
image — image & tag
image:
repository: kumaravinit/zero
tag: "licensing-portal-1.0.1" # or "licensing-portal-latest"
pullPolicy: IfNotPresent
Install command
helm install zero-licensing ./helm/zero-licencing-portal \
-f helm/zero-licencing-portal/values.yaml \
--namespace zero-licensing --create-namespace
Quick Summary: What Goes Where
| Concern | Docker Compose | Helm |
|---|---|---|
| Non-secret config | .env file |
values.yaml → env: block |
| Secrets | .env file (keep secure) |
Separate values-secrets.yaml → secrets: block → K8s Secret |
| Image version | Override image: line in compose |
image.tag in values |
| DB connection (IDS) | Auto-wired via service name postgres |
DB_HOST: postgresql-service |
| DB connection (Portal compose) | Auto-built inside compose file | secrets.databaseUrl |
| First-boot seed | AUTO_SEED=true |
backend.env.AUTO_SEED: "true" |
| Self-hosted mode | SELF_HOSTED=true + LICENSE_KEY=... |
backend.env.SELF_HOSTED: "true" + LICENSE_KEY |