Skip to main content

Environments pattern

How we distinguish development, acceptance, and production environments across backend, frontend, and deployment.

Overview

We distinguish three environments — development (local), acceptance (deployed pre-production), and production (live). They drive CORS, logging verbosity, and optional feature flags.

Detection

  • Backend: ENVIRONMENT env var (lowercase development, acceptance, production); when unset, default to Development. Locally ENVIRONMENT is usually unset; app specs set ENVIRONMENT to acceptance or production for deployment.
  • Frontend: VITE_ENVIRONMENT (build-time) in the DO app specs, or import.meta.env.DEV in local dev. When unset and not DEV, default to Development.

Backend

Use getEnvironment() (returns shared Environment enum from shared/environments) instead of reading NODE_ENV directly. CORS: allow all origins in development only; restrict in acceptance and production. Other code (e.g. logging, feature flags) can branch on getEnvironment().

Frontend

Static site envs in DO app specs list VITE_ENVIRONMENT as the first entry (before VITE_BACKEND_URL), value acceptance or production (lowercase to match shared enum). Frontend can use getEnvironment() in frontends/shared that reads import.meta.env.VITE_ENVIRONMENT and returns the shared Environment enum (Development when unset or when DEV).

Implementation

  • Shared: Export Environment enum from shared/environments (file shared/src/environments.ts). Values: Development = 'development', Acceptance = 'acceptance', Production = 'production'.
  • Backend: getEnvironment() in backend/src/config/environment.ts, reading process.env.ENVIRONMENT only (no NODE_ENV fallback); when unset, return Environment.Development. backend/src/main.ts uses it for CORS (origin: getEnvironment() === Environment.Development). .env.example documents optional ENVIRONMENT.
  • DO app specs (.do/app-acc.yaml, .do/app-prod.yaml): (1) Backend service: ENVIRONMENT as the first entry in envs (before NODE_ENV), value acceptance or production (lowercase). (2) Static_sites (frontend): VITE_ENVIRONMENT as the first entry in envs (before VITE_BACKEND_URL), value acceptance or production, scope BUILD_TIME.
  • Frontend: frontends/shared/src/lib/environment.ts exports getEnvironment() (reads import.meta.env.VITE_ENVIRONMENT and import.meta.env.DEV, returns Environment from shared/environments). frontends/shared/src/env.d.ts declares VITE_ENVIRONMENT?: string.

References

  • Stack: configuration, hosting.
  • Capability: auth (CORS with credentials).