SyntaxStudy
Sign Up
Next.js Self-Hosting with Node.js and Docker
Next.js Beginner 1 min read

Self-Hosting with Node.js and Docker

Next.js can be self-hosted on any server that runs Node.js 18.17 or later. Running npm run build generates the .next/ directory containing the compiled application. Running npm run start (which runs next start) starts the production HTTP server. You can pass -p to specify a port and use a process manager like PM2 to keep the server running and restart it on crashes. For containerised deployments with Docker, set output: 'standalone' in next.config.js. This produces a .next/standalone directory containing only the files needed to run the server, with all node_modules dependencies bundled — typically 90% smaller than the full node_modules folder. You copy the standalone output, the static files, and the public directory into a minimal Node.js Docker image. The standalone output does not include the .next/static folder or the public/ folder — you must copy these separately. The included server.js file is a minimal HTTP server you run directly with node server.js. You can pass PORT and HOSTNAME environment variables to configure where the server listens. This Docker approach works with any container orchestration platform: Kubernetes, AWS ECS, Google Cloud Run, or Railway.
Example
# Dockerfile for Next.js standalone output

FROM node:20-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Build the application
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build

# Production image — minimal
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy standalone output
COPY --from=builder /app/.next/standalone ./
# Copy static assets (NOT included in standalone)
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Copy public directory
COPY --from=builder /app/public ./public

USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]