Docker
Learn how to deploy your application as a Docker container.
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:
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:
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:
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
.env*.localBuild and Run Locally
Test your Docker image locally:
docker build -t my-app .
docker run -p 3000:3000 --env-file .env my-appDeploy to Any Platform
You can now deploy this Docker image to any platform that supports Docker:
- Fly.io - See Fly.io deployment guide
- Railway - See Railway deployment guide
- Render - See Render deployment guide
- AWS ECS/Fargate - Use AWS container services
- Google Cloud Run - Serverless container platform
- DigitalOcean App Platform - Managed container hosting
- Your own server - Deploy to any VPS with Docker
Environment Variables
Make sure to set all required environment variables when running the container:
docker run -p 3000:3000 \
-e DATABASE_URL="postgresql://..." \
-e BETTER_AUTH_SECRET="..." \
-e NEXT_PUBLIC_SITE_URL="https://your-app.com" \
my-appOr use an environment file:
docker run -p 3000:3000 --env-file .env.production my-appDatabase Migrations
Create and review migrations during development:
npm run db:migrate:dev -- --name describe_the_changeCommit the generated files in prisma/migrations/ with the schema change. In
production, apply those committed migrations once as a release step:
npm run db:migrateThe 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.
Keep migrations out of the image buildA Docker build should not connect to or mutate a production database. Avoid running migrations in the Dockerfile. Also avoid starting the migration command independently in every application replica because several containers may start at the same time.
Troubleshooting
SSL Errors
If you encounter SSL errors like ERR_SSL_PACKET_LENGTH_TOO_LONG, ensure your DATABASE_URL includes SSL parameters:
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 innext.config.ts
For the complete container workflow, including runtime secrets, health checks and reverse proxies, read Self-Host a Next.js SaaS With Docker.