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. LocallyENVIRONMENTis usually unset; app specs setENVIRONMENTtoacceptanceorproductionfor 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(fileshared/src/environments.ts). Values:Development = 'development',Acceptance = 'acceptance',Production = 'production'. - Backend: getEnvironment() in
backend/src/config/environment.ts, readingprocess.env.ENVIRONMENTonly (no NODE_ENV fallback); when unset, returnEnvironment.Development. backend/src/main.ts uses it for CORS (origin: getEnvironment() === Environment.Development). .env.example documents optionalENVIRONMENT. - DO app specs (
.do/app-acc.yaml,.do/app-prod.yaml): (1) Backend service: ENVIRONMENT as the first entry inenvs(before NODE_ENV), valueacceptanceorproduction(lowercase). (2) Static_sites (frontend): VITE_ENVIRONMENT as the first entry inenvs(before VITE_BACKEND_URL), valueacceptanceorproduction, scope BUILD_TIME. - Frontend: frontends/shared/src/lib/environment.ts exports getEnvironment() (reads
import.meta.env.VITE_ENVIRONMENTandimport.meta.env.DEV, returnsEnvironmentfromshared/environments). frontends/shared/src/env.d.ts declaresVITE_ENVIRONMENT?: string.
References
- Stack:
configuration,hosting. - Capability:
auth(CORS with credentials).