Deploying a Next.js App in Standalone Mode to OpenShift / Kubernetes


Most Next.js tutorials assume you deploy on Vercel. That works great — until you are in an enterprise environment where:

  • You must deploy into OpenShift or a Kubernetes cluster
  • You need a custom Node.js runtime image
  • You want full control over networking, certificates, and scaling

In this post, we’ll walk through how to deploy a Next.js app in standalone mode, using a normal build process and a custom Docker image — no Vercel involved.


Why Standalone Mode?



Next.js standalone mode bundles:

  • The compiled server (server.js)
  • Only the required Node.js dependencies
  • A minimal runtime footprint

This makes it ideal for containerized environments like OpenShift and Kubernetes.


1️⃣ Build the App Normally

There is nothing special here. You still install dependencies and run a standard Next.js build:

npm ci
npm run build

Your next.config.js must enable standalone output:

module.exports = {
  output: 'standalone',
};

2️⃣ Understand the Build Output

After the build, Next.js generates a folder like:

.next/standalone

Inside it, you’ll find:

  • A minimal node_modules
  • The compiled server entry: .next/standalone/apps/<your-app>/server.js

Important: Static assets and public files are not automatically copied. You must do this yourself.


3️⃣ Copy Static and Public Assets

This is the key step many people miss. After the build, copy static files into the standalone folder:

cp -R dist/apps/example-app/.next/static \
  dist/apps/example-app/.next/standalone/dist/apps/example-app/.next/static

cp -R dist/apps/example-app/public \
  dist/apps/example-app/.next/standalone/apps/example-app/public

Now the standalone server can correctly serve:

  • /_next/static/*
  • /public/*

4️⃣ Dockerfile for OpenShift / Kubernetes

Below is a simplified Dockerfile using a custom Node.js runtime image. The image name and app path are intentionally generalized.

FROM image-registry.openshift-image-registry.svc:5000/internal/nodejs-runtime:22

WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

USER root
ADD app.tar.gz .

RUN chown -R 1001:0 /app && chmod -R g+rwx /app

USER 1001

EXPOSE 3000
ENV PORT=3000

CMD NODE_EXTRA_CA_CERTS=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
node .next/standalone/apps/example-app/server.js

Key points:

  • No development dependencies
  • No next start
  • We run the generated server.js directly

5️⃣ Why This Works Well in OpenShift



  • Runs as a non-root user (UID 1001)
  • Compatible with OpenShift SCC restrictions
  • Fast startup time
  • Small runtime footprint

This pattern works equally well for:

  • OpenShift
  • Vanilla Kubernetes
  • On-prem clusters
  • Private cloud environments

Final Thoughts

You don’t need Vercel to run Next.js properly. With standalone output and a small amount of asset wiring, you get a clean, production-ready deployment that fits perfectly into enterprise Kubernetes platforms.

If you’re already building Next.js apps for large organizations, this approach gives you control, predictability, and portability.

❤️ Support This Blog


If this post helped you, you can support my writing with a small donation. Thank you for reading.


Comments

Popular posts from this blog

fixed: embedded-redis: Unable to run on macOS Sonoma

Copying MDC Context Map in Web Clients: A Comprehensive Guide

Reset user password for your own Ghost blog