Skip to content

Environment Variables — Index

Pointer page. The canonical catalogue is ../env-reference.md (every var across all three repos, grouped by category) and the local-vs-prod diff is at ../env-reference-diff.md. This page summarises how envs are loaded and where secrets come from.


Loading mechanism by repo

Repo Mechanism Templates
ebit-api env-cmd -f .env (via npm scripts); validated at startup by libs/shared/src/env-config/env.dto.ts .example.env, .local.env, .test.env
ebit-fe Next.js built-in process.env + NEXT_PUBLIC_* client-side injection .example.env
ebit-admin-fe Same as ebit-fe .example.env
Root compose docker-compose.yml environment: blocks; ${VAR:-default} for host-port overrides

.env files are gitignored. Never commit real secrets; the templates ship dev-safe placeholders.

For ebit-api, the env validator is strict: @IsString() without @IsOptional() plus skipMissingProperties: false means any missing required variable crashes the boot. The validator is libs/shared/src/env-config/env.dto.ts — read it when adding a new env to know which decorators are needed.


Doppler — secrets management

Workspace: ebit-devops (slug 4d59619bf8c6f858715b). Per memory reference_doppler_workspace.

Layout

Project Secret count Source baseline
ebit-api ~121 keys in dev_perf config uploaded from .local.env
ebit-fe 11 keys in dev_perf config uploaded from .example.env
ebit-admin-fe 11 keys in dev_perf config uploaded from .example.env

Environments per project: dev / stg / prd (auto-created). Only the dev_perf branch config is populated today; stg / prd are intentionally empty until the perf rig hands over to a pre-prod environment.

Personal token (admin scope)

  • Persisted: ~/.config/doppler/token (chmod 600).
  • Loaded in shell via ~/.bashrc: export DOPPLER_TOKEN=$(cat ~/.config/doppler/token 2>/dev/null).
  • Token rotation: requested by the user post-perf-run; coordinate with team lead.

Service tokens (container runtime)

Each project has a scoped service token used by doppler run --token <tok> -- node main.js inside containers (Dockerfiles in ebit-api wrap their CMD with doppler run). Tokens persist on the perf-rig workstation:

  • terraform/perf/secrets/doppler-token-ebit-api
  • terraform/perf/secrets/doppler-token-ebit-fe
  • terraform/perf/secrets/doppler-token-ebit-admin-fe

secrets/ is gitignored in terraform/perf/.gitignore.

CLI cheatsheet

doppler projects                                          # list projects
doppler configs --project ebit-api                        # list configs in project
doppler secrets --project ebit-api --config dev_perf      # view secrets
doppler secrets set KEY=value --project X --config dev_perf
doppler run --token <service-token> -- node main.js       # run with secrets injected

Production deployment — where each var comes from

Source What lives there Examples
Doppler (stg / prd configs, when populated) Application secrets (JWT keys, DB URLs, API keys) JWT_SECRET, DATABASE_URL, REDISCLOUD_URL, SENDGRID_API_KEY, all SENTRY_DSN_*, all OAuth client secrets
Terraform output (terraform/perf/outputs.tf) Infrastructure-derived URLs and IPs monitoring_url, grafana_url, jaeger_url, sut_public_ip, loadgen_public_ip
Build args (Dockerfile / Next.js build) NEXT_PUBLIC_* client-side bundles, source-map upload NEXT_PUBLIC_API_URL, NEXT_PUBLIC_SENTRY_DSN, SENTRY_AUTH_TOKEN
Compose ${VAR:-default} Host port overrides, dev-only flags POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD
.env (local only) Dev-safe placeholders Same key set as .example.env

For perf-test specifics see ../audits/doppler-perf-audit.md which documents the dev_perf audit, two showstoppers fixed in-place (FASTTRACK_JWT_PRIVATE_KEY / FASTTRACK_JWT_PUBLIC_KEY missing; JWT_SECRET contaminated with multi-line junk), and one pending issue (NODE_ENV=production breaks captcha bypass used by seed scripts).


Top must-change-for-prod vars

From ../env-reference-diff.md. Deploying without changing these will cause outages or vulnerabilities.

Variable Local default Production requirement Risk if unchanged
DATABASE_URL postgresql://ebit:ebit@ebit-db:5432/ebit Managed Postgres, strong creds Open DB, default password
REDISCLOUD_URL redis://:cache@ebit-redis:6379/0 Managed Redis Public Redis with password cache
JWT_SECRET dev placeholder Cryptographically random, ≥256-bit Token forgery
SESSION_SECRET dev placeholder Cryptographically random Session hijacking
JWT_MFA_TEMP_SECRET dev placeholder Cryptographically random 2FA bypass
NODE_ENV local production Sentry off, email bypass on, captcha bypass on
APP_FE_ORIGIN http://localhost:3000 https://dropbet.com CORS blocks real users
APP_FE_ORIGIN_ADMIN http://localhost:3001 https://admin.dropbet.com Admin CORS broken
BASE_DOMAIN localhost dropbet.com Cookie scope wrong
ADMIN_DEFAULT_PASSWORD admin Strong password or remove seed Admin account with password admin

The full table (must-change + must-provision + behaviour-by-NODE_ENV matrix) is in ../env-reference-diff.md.


Behaviour gated on NODE_ENV=local

These behaviours are on in local dev and off in production. Forgetting to flip means tests rely on something that doesn't exist in prod.

Behaviour When on
Captcha bypass via x-captcha-token: pass NODE_ENV=local (apps/api/src/captcha/google/recaptcha.service.ts:28)
Email sending bypassed (SendGrid sendEmail() returns immediately) NODE_ENV=local
Sentry error reporting disabled NODE_ENV=local regardless of DSN
Pretty-printed logs (pino-pretty) NODE_ENV=local + DEBUG_LOGS_PRETTY=true
Socket.IO admin UI NODE_ENV=local + DEBUG_SOCKET_IO_ADMIN=true
In-memory feature flags FEATURE_FLAGS_USE_LOCAL=true (regardless of NODE_ENV)
Demo seed user created DEBUG_SEED_LOCAL=true (should never be set in prod)

Adding a new env variable

  1. Add it to the relevant repo's .example.env with a dev-safe placeholder.
  2. For ebit-api: add the field to libs/shared/src/env-config/env.dto.ts with the right class-validator decorator (@IsString(), @IsOptional(), @IsNumber(), etc.).
  3. For FE: prefix client-side vars with NEXT_PUBLIC_* so Next.js inlines them.
  4. Add a row to ../env-reference.md under the right category (Database / Redis cache / Redis bot / Auth / OAuth / etc.).
  5. If it's required in production: add a row to ../env-reference-diff.md.
  6. Push the secret to Doppler:
    doppler secrets set NEW_KEY="value" --project ebit-api --config dev_perf
    
  7. If the var is [SECRET], mark it in the env-reference table.

See also