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.jsdirectly
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
Post a Comment