Managing Environment Variables and Secrets for Next.js in Kubernetes
Managing Environment Variables and Secrets for Next.js in Kubernetes
This is Part 5 of the series: Self-Hosting Next.js in Kubernetes (Without Vercel).
By now, your Next.js standalone app is:
- Built correctly
- Running in a minimal Docker image
- Deployed on OpenShift or Kubernetes
The next challenge is managing configuration and secrets without rebuilding your image every time.
Build-Time vs Runtime Environment Variables
This distinction is critical in Next.js.
Build-Time Variables
- Resolved during
npm run build - Inlined into the JavaScript bundle
- Cannot be changed without rebuilding
Examples:
NEXT_PUBLIC_API_URL
NEXT_PUBLIC_FEATURE_FLAG
Runtime Variables
- Read when
server.jsstarts - Can be changed via Kubernetes
- Ideal for secrets and environment-specific config
DATABASE_URL
REDIS_HOST
INTERNAL_API_TOKEN
What Works Best for Standalone Deployments
For self-hosted Next.js:
- Use build-time vars sparingly
- Prefer runtime vars for everything else
- Avoid baking secrets into the image
The standalone server behaves like a normal Node.js app — use that to your advantage.
Using ConfigMaps
ConfigMaps are ideal for non-sensitive configuration.
apiVersion: v1
kind: ConfigMap
metadata:
name: example-nextjs-config
data:
LOG_LEVEL: "info"
API_TIMEOUT_MS: "5000"
Attach them to your Deployment:
envFrom:
- configMapRef:
name: example-nextjs-config
Using Secrets
Secrets should be used for anything sensitive.
apiVersion: v1
kind: Secret
metadata:
name: example-nextjs-secrets
type: Opaque
stringData:
DATABASE_URL: "postgres://..."
API_TOKEN: "********"
Mount them into the container:
envFrom:
- secretRef:
name: example-nextjs-secrets
Your standalone server can access them via process.env.
Common Mistake: NEXT_PUBLIC at Runtime
Variables prefixed with NEXT_PUBLIC_ are:
- Resolved at build time
- Embedded into client-side JavaScript
Changing them in Kubernetes will not update the UI.
If a value must be dynamic, fetch it from the server at runtime instead of embedding it in the bundle.
Example Deployment Snippet
containers:
- name: web
image: example-nextjs:latest
envFrom:
- configMapRef:
name: example-nextjs-config
- secretRef:
name: example-nextjs-secrets
No rebuild required — just redeploy.
Security Best Practices
- Never commit secrets to source control
- Rotate secrets without rebuilding images
- Limit access via RBAC
- Use external secret managers when available
Series Progress
Self-Hosting Next.js in Kubernetes (Without Vercel)
- ✅ Part 1: Standalone Deployment
- ✅ Part 2: Minimal Docker Images
- ✅ Part 3: OpenShift Deployment
- ✅ Part 4: Fixing Static Asset 404s
- ✅ Part 5: Runtime Config & Secrets
- ⏭ Part 6: Health Checks & Scaling
Final Thoughts
Once you separate build-time and runtime configuration, Next.js becomes much easier to operate in Kubernetes.
In the final post, we’ll cover health probes, graceful shutdowns, and horizontal scaling strategies.
❤️ Support This Blog
If this post helped you, you can support my writing with a small donation. Thank you for reading.
Comments
Post a Comment