Skip to main content
General
Deployment

Docker

Learn how to deploy your application as a Docker container.

Open MarkdownFull AI corpusFeedback

Deploying your application as a Docker container gives you control over the server environment, better privacy, potential cost savings, and flexibility to customize your setup. It can also improve performance compared to serverless platforms by removing cold starts.

Setup Next.js for Docker Deployment

Configure Next.js to build as a standalone app for containerization. Update your next.config.ts:

next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  // ... other config
  output: 'standalone'
};

export default nextConfig;

Create Dockerfile

Create a Dockerfile in the root of your project:

Dockerfile
FROM node:22.21.1-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Copy package files
COPY package.json package-lock.json* ./
RUN npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Generate Prisma Client
RUN npx prisma generate

# Build the application
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

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

# Copy the standalone build
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
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

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

Create .dockerignore

Create a .dockerignore file in the root:

.dockerignore
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
.env*.local

Build and Run Locally

Test your Docker image locally:

Terminal
docker build -t my-app .
docker run -p 3000:3000 --env-file .env my-app

Deploy to Any Platform

You can now deploy this Docker image to any platform that supports Docker:

Environment Variables

Make sure to set all required environment variables when running the container:

Terminal
docker run -p 3000:3000 \
  -e DATABASE_URL="postgresql://..." \
  -e BETTER_AUTH_SECRET="..." \
  -e NEXT_PUBLIC_SITE_URL="https://your-app.com" \
  my-app

Or use an environment file:

Terminal
docker run -p 3000:3000 --env-file .env.production my-app

Database Migrations

Create and review migrations during development:

Terminal
npm run db:migrate:dev -- --name describe_the_change

Commit the generated files in prisma/migrations/ with the schema change. In production, apply those committed migrations once as a release step:

Terminal
npm run db:migrate

The production command maps to prisma migrate deploy. Run it in CI before replacing the application containers or use a one-off migration task provided by your container platform. Wait for it to succeed before directing traffic to the new revision.

Troubleshooting

SSL Errors

If you encounter SSL errors like ERR_SSL_PACKET_LENGTH_TOO_LONG, ensure your DATABASE_URL includes SSL parameters:

.env
DATABASE_URL="postgresql://user:pass@host:5432/db?sslmode=require"

Port Configuration

Make sure the port in your Dockerfile matches your Next.js configuration and the port you expose when running the container.

Build Failures

If the build fails, check:

  • Node.js version is 22.21.1, matching package.json
  • All dependencies are properly installed
  • Prisma Client generation completes successfully
  • Every environment variable required by the application build is available
  • output: 'standalone' remains enabled in next.config.ts

For the complete container workflow, including runtime secrets, health checks and reverse proxies, read Self-Host a Next.js SaaS With Docker.