Reading environmental variables set in configmap of kubernetes pod from react application?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
React applications built with Create React App (or Vite) are static files that run in the browser, not on the server. This means process.env is resolved at build time, not at runtime. You cannot directly read Kubernetes ConfigMap environment variables from a running React application the way a Node.js backend can. The solution is to either inject environment variables at build time, serve a runtime configuration file from the container, or use an API endpoint that returns configuration values.
The Problem
A ConfigMap injects environment variables into a pod:
But inside the React code, process.env.REACT_APP_API_URL is replaced with its value during npm run build. It does not read from the container's environment at runtime.
Solution 1: Build-Time Injection
Set environment variables before building the Docker image:
Downside: You need a separate Docker image for each environment (dev, staging, production). This defeats the purpose of ConfigMaps, which are meant to decouple configuration from images.
Solution 2: Runtime Config File (Recommended)
Generate a JavaScript config file at container startup that reads environment variables:
Include the config file in public/index.html:
Access in React:
Now the same Docker image works in all environments. The ConfigMap controls the values injected at pod startup.
Solution 3: ConfigMap as a Volume-Mounted File
Mount the ConfigMap as a JSON file instead of environment variables:
Solution 4: API Endpoint
Serve configuration through a backend API:
This requires an additional backend service but provides the most flexibility, including the ability to change configuration without restarting pods.
Vite Projects
For Vite-based React apps, environment variables use the VITE_ prefix:
The runtime config approach works the same way. Only the build-time variable prefix changes from REACT_APP_ to VITE_.
Common Pitfalls
- Assuming
process.envworks at runtime in React: React (CRA/Vite) replacesprocess.env.REACT_APP_*with literal strings at build time. They cannot read pod environment variables at runtime. - Forgetting the
REACT_APP_prefix: Create React App only exposes environment variables prefixed withREACT_APP_. Variables without this prefix are ignored during the build. Vite usesVITE_instead. - Storing secrets in ConfigMaps: ConfigMaps are not encrypted. Use Kubernetes Secrets for API keys, tokens, and passwords. Even with Secrets, avoid exposing sensitive values to frontend code.
- Caching the config.js file: Browsers may cache
config.jsaggressively. Add a cache-busting query string (config.js?v=timestamp) or setCache-Control: no-cacheheaders in nginx for this file. - Not loading config before rendering: If using fetch-based config (Solution 3/4), the config may not be available when components first render. Load config before calling
ReactDOM.createRoot().render()or show a loading state.
Summary
- React apps cannot read Kubernetes ConfigMap environment variables at runtime because
process.envis resolved at build time - The recommended approach is generating a
config.jsfile at container startup using an entrypoint script - Alternatively, mount a ConfigMap as a JSON file served by the web server
- Use the same Docker image across all environments by decoupling configuration from the build
- Never expose secrets in frontend configuration — use backend APIs for sensitive values
Related reading
- Reattach a Dynamically Provisioned PV to a PVC
- Recommended way to configure max_prepared_transactions in Postgres on Kubernetes
- Recover a Kubernetes Cluster
- Redirect http port to nodePort
- Real-time application newbie - Node.JS + Redis or RabbitMQ -> client/server how?
- Reanimated 2 failed to create a worklet, maybe you forgot to add Reanimated''s babel plugin?
- Redirect non www to www using ALB Ingress Controller
- Redis master/slave setup on Kubernetes throwing error BRPOPLPUSH ReplyError MOVED 2651

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.