Guide: React + Vite + Bun (Runtime Variables with Nginx)
Guide: React + Vite + Bun (Runtime Variables with Nginx)
This setup allows your React application’s environment variables to be defined at container startup time, removing the need to generate a different build for each environment (Development, Staging, Production).
You can find more information about the plugin here: vite-plugin-runtime-env
1. Requirements
Install the plugin as a development dependency:
bun add -D vite-plugin-runtime-env
2. Vite Configuration (vite.config.ts)
The plugin automatically detects variables with the VITE_ prefix and prepares the code for runtime substitution.
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import path from "path";
import runtimeEnv from "vite-plugin-runtime-env";
export default defineConfig({
plugins: [
react(),
runtimeEnv() // Processes variables so Nginx can inject them
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});
3. Nginx Configuration (nginx.conf)
Optimized configuration for Single Page Applications (SPA).
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# SPA fallback
location / {
try_files $uri $uri/ /index.html;
}
# Gzip for better performance
gzip on;
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
}
4. Containerfile (Containerfile)
Uses an immutable template system to allow infinite variable changes without rebuilding.
# ---------- Build ----------
FROM oven/bun:1.3.0-alpine AS build
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun run build
# ---------- Runtime ----------
FROM nginx:1.27-alpine
WORKDIR /usr/share/nginx/html
# Cleanup and configuration
RUN rm -f /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy the build output
COPY --from=build /app/dist .
# Create immutable template for envsubst
RUN cp index.html index.html.template
EXPOSE 80
# Dynamic injection at container startup
CMD ["/bin/sh", "-c", "envsubst < index.html.template > index.html && nginx -g 'daemon off;'"]
5. Docker Compose Deployment
Define your variables here. Changes will take effect with a simple container restart.
services:
web:
build: .
environment:
- VITE_API_URL=https://api.company.com
- VITE_ENVIRONMENT=production
ports:
- "80:80"
💡 How It Works
-
Build Time: The plugin vite-plugin-runtime-env leaves placeholders in the compiled JavaScript/HTML using the ${VITE_VARIABLE} format.
-
Runtime (Container Startup): When the container starts, the envsubst command takes the template
(index.html.template), finds those placeholders, and replaces them with the actual environment variable values. -
Persistence: By using a template file
(.template), you can restart the container with new values as many times as needed—the variable “slots” are always available for reinjection.
Note: Make sure environment variables in your code are still accessed via import.meta.env.VITE_... to maintain compatibility with the plugin.