
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
To successfully run Next.js on Kubernetes, you must treat it as a stateful Node.js service rather than a static site, requiring specific Docker optimizations and cluster configurations. Many teams struggle because they apply generic Node.js patterns that fail to account for Next.js hybrid rendering, image optimization caches, and server-side telemetry. This guide provides the exact production-grade configuration I use to deploy scalable Next.js applications on managed and self-hosted clusters.
How do you optimize a Next.js Docker image for Kubernetes?
The foundation of any stable Kubernetes deployment is the container image itself. When you run Next.js on Kubernetes, bloated images cause slow scale-up times and increased attack surfaces. A common mistake is copying the entire node_modules directory into the final runtime stage. Instead, leverage the output: 'standalone' option in next.config.js, which traces dependencies and produces a minimal self-contained folder.
Your Dockerfile should follow this precise structure to ensure compatibility with Kubernetes security standards and fast pod scheduling:
# syntax=docker/dockerfile:1
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"] Note the explicit HOSTNAME="0.0.0.0". By default, Next.js standalone server binds to localhost, which makes it unreachable from other pods or the Ingress controller within the Kubernetes network. Setting this environment variable is mandatory for cluster connectivity. For deeper guidance on reducing image layers and vulnerability scanning, refer to our article on how to reduce Docker image size with multi-stage builds.
How do you configure Ingress and networking for Next.js?
Networking is where most deployments fail when users attempt to run Next.js on Kubernetes. The application requires proper header forwarding to handle Server-Side Rendering (SSR) correctly. Without X-Forwarded-Host and X-Forwarded-Proto, Next.js may generate incorrect absolute URLs for redirects, canonical tags, and Open Graph metadata.
If you are using NGINX Ingress Controller, your annotation block must explicitly pass these headers. Here is a battle-tested Ingress manifest snippet:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nextjs-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nextjs-service
port:
number: 3000 For teams managing complex microservices architectures, understanding the broader networking layer is critical. I recommend reviewing Kubernetes Ingress controllers explained to compare NGINX, Traefik, and Cilium Gateway API implementations before finalizing your routing strategy. Misconfigured ingress is the leading cause of "works locally, breaks in prod" issues for SSR frameworks.
How do you manage state and caching in a Kubernetes cluster?
Next.js maintains an in-memory cache for ISR (Incremental Static Regeneration) and route handlers by default. In a single-pod setup, this works fine. When you run Next.js on Kubernetes with multiple replicas, each pod maintains its own isolated cache. This leads to inconsistent content delivery where one user sees updated data while another sees stale pages.
To solve this, you have two primary architectural options:
- Shared Cache Adapter: Configure Next.js to use Redis or Memcached as a centralized cache store. This ensures all pods read/write from the same source of truth. Libraries like
@neshca/cache-handlerprovide drop-in adapters for Next.js App Router. - Sticky Sessions: Configure your Ingress or Service Mesh to route requests from the same client IP/session to the same pod. This preserves local cache consistency but reduces the effectiveness of load balancing and complicates rolling updates.
I strongly prefer the shared cache adapter approach. Sticky sessions create operational fragility during scaling events and deployments. If your application relies heavily on ISR, treating the cache as ephemeral per-pod state will inevitably lead to data drift. For persistent storage needs beyond caching, such as media uploads or generated assets, consult Kubernetes persistent volumes and storage to avoid losing data during pod restarts.
How do you implement autoscaling and resource limits?
Resource management distinguishes a hobbyist setup from a production system. When you run Next.js on Kubernetes, you must define both requests and limits. Requests guarantee schedulable resources; limits prevent noisy neighbors. Next.js can be memory-hungry during build-time hydration and SSR rendering spikes.
| Configuration | Development / Staging | Production Baseline | High-Traffic E-commerce |
|---|---|---|---|
| CPU Request | 100m | 250m | 500m |
| CPU Limit | 500m | 1000m | 2000m |
| Memory Request | 256Mi | 512Mi | 1Gi |
| Memory Limit | 512Mi | 1Gi | 2Gi |
| Replicas (Min) | 1 | 2 | 3 |
| HPA Target CPU | 80% | 65% | 50% |
Avoid setting memory limits too close to requests. Node.js garbage collection behaves poorly under extreme memory pressure, leading to latency spikes before OOMKill occurs. I typically set limits at 2x requests for Next.js workloads. Pair this with Horizontal Pod Autoscaler (HPA) configured for CPU utilization initially, then graduate to custom metrics like request latency or queue depth once you have sufficient observability data. See horizontal pod autoscaling in Kubernetes for advanced metric configurations.
What security hardening steps are mandatory for production?
Security cannot be an afterthought when operating web frameworks in orchestrated environments. Running as root inside a container is unacceptable in 2026. Your Dockerfile must include a non-root user directive, and your Pod Security Standards should enforce restricted profiles.
- Read-Only Root Filesystem: Set
readOnlyRootFilesystem: truein your security context. Mount/tmpand/.next/cacheas emptyDir volumes if write access is absolutely necessary. This prevents attackers from modifying binaries post-exploitation. - Secrets Management: Never bake API keys or database credentials into the Docker image. Use Kubernetes Secrets mounted as environment variables or files. For higher assurance, integrate HashiCorp Vault or AWS Secrets Manager via CSI drivers.
- Network Policies: Restrict egress traffic. Your Next.js pods likely only need access to your database, cache, and external APIs. Block all other outbound connections to limit lateral movement potential.
- Image Scanning: Integrate Trivy or Grype into your CI pipeline. Fail builds on critical CVEs. Runtime scanning should also be active to detect vulnerabilities introduced through base image updates.
Compliance frameworks like SOC 2 and ISO 27001 specifically audit these controls. Automated evidence collection for these configurations saves hundreds of hours during audit cycles. Proper Kubernetes secrets management done right is often the difference between passing and failing a security review.
Run Next.js on Kubernetes with Confidence
Migrating a modern React framework to orchestrated containers demands respect for both application semantics and infrastructure primitives. When you run Next.js on Kubernetes correctly, you gain predictable scaling, improved resilience, and unified operational tooling across your entire stack. Start with the standalone Docker pattern, enforce strict networking headers, centralize your caching layer, and never skip security hardening. These fundamentals separate fragile demos from systems that survive Black Friday traffic and compliance audits alike.
If your team needs assistance architecting a production-grade Next.js platform or auditing existing deployments for performance and security gaps, reach out to discuss your infrastructure requirements. I help organizations build cloud-native systems that are secure, observable, and genuinely maintainable.