0005: Frontend Build and Configuration Strategy
Date: 2025-08-10
Status: Revised
Context
Frontend applications, such as the shell-app, need to connect to different backend environments (development, staging, production). Each environment has unique configuration values, such as API endpoints or feature flags.
A naive approach would be to use build-time environment files (e.g., Angular's environment.ts or a .env file with Vite). This would require building a separate container image for each environment, which violates the principle of a single, immutable build artifact that is promoted through environments. We need a strategy that decouples the build artifact from its runtime configuration.
Decision
We will adopt a runtime configuration model for all frontend applications.
- Build Process: Frontend applications will be built into a set of static assets (HTML, CSS, JS) using their standard toolchain (e.g.,
ng build). - Serving: These static assets will be served by a lightweight web server (e.g., Nginx) within a Docker container. This container image is the single, immutable build artifact.
- Configuration File: The Nginx server will serve a special file at a known path,
/assets/config.json. This file will contain all environment-specific variables. - Configuration Loading:
- The frontend application, upon startup, will make an HTTP request to fetch
/assets/config.json. - This request must complete before the application fully bootstraps to ensure the configuration is available. Most modern frameworks provide a mechanism to block initialization until an asynchronous task (like fetching this file) is complete.
- The loaded configuration will be stored in a dedicated, injectable service or a global state object.
- The frontend application, upon startup, will make an HTTP request to fetch
- Configuration Provisioning:
- The
config.jsonfile will not be baked into the container image. - In our Kubernetes environment, the configuration for each environment will be stored in a
ConfigMap. - This
ConfigMapwill be mounted as a volume into the Nginx container at/usr/share/nginx/html/assets/config.json, effectively injecting the correct configuration at deploy time.
- The
Consequences
Positive
- Build Once, Deploy Anywhere: A single container image can be promoted across all environments (dev, staging, prod) without modification.
- Decoupling: The build artifact is completely decoupled from the runtime environment. Configuration changes do not require a new build.
- Security: Secrets and environment-specific details are managed by the deployment environment (e.g., Kubernetes), not stored in source code or build artifacts.
- Consistency: All frontend applications will follow the same, predictable pattern for configuration.
Negative
- Startup Latency: There is a small, one-time latency penalty on application startup due to the extra HTTP request to fetch the configuration file. This is considered an acceptable trade-off for the significant benefits.
- Container Complexity: The Nginx container requires a simple entrypoint script to handle runtime substitutions, which adds a minor layer of complexity compared to a purely static container.