dev3 ·
I want to run Next.js 15 in Docker on my VPS. My image is over 1 GB. How do I produce a small production image and pass environment variables properly?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
I want to run Next.js 15 in Docker on my VPS. My image is over 1 GB. How do I produce a small production image and pass environment variables properly?
Use output: "standalone" and a multi-stage build. Next traces the needed files into .next/standalone.
// next.config.ts
import type { NextConfig } from "next";
const config: NextConfig = { output: "standalone" };
export default config;
# Dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG NEXT_PUBLIC_SITE_URL
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
RUN npm run build
FROM node:22-alpine AS run
WORKDIR /app
ENV NODE_ENV=production PORT=3000 HOSTNAME=0.0.0.0
RUN addgroup -S app && adduser -S app -G app
COPY --from=build /app/public ./public
COPY --from=build --chown=app:app /app/.next/standalone ./
COPY --from=build --chown=app:app /app/.next/static ./.next/static
USER app
EXPOSE 3000
CMD ["node", "server.js"]
public and .next/static are not copied into standalone automatically; copy them as shown.node server.js, not next start.NEXT_PUBLIC_* must be present at build time (build args). Server secrets are passed at runtime: docker run --env-file .env.production -p 3000:3000 image.HOSTNAME=0.0.0.0 is needed so the container accepts traffic from outside..dockerignore with node_modules, .next, .git, .env*.X-Forwarded-* headers.sharp work on Alpine for current Next versions; if you hit libc issues use node:22-slim.Pitfall: images that do not set HOSTNAME listen only on the container's own hostname and health checks fail.
The Dockerfile and Compose generator can scaffold a similar setup.