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:20-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
For production deployments, run migrations before starting the app. You can:
- Run migrations in the Dockerfile (during build)
- Run migrations as a separate step before starting the container
- Use an init container in orchestration platforms
Example with a startup script:
#!/bin/sh
npx prisma migrate deploy
exec node server.jsUpdate Dockerfile:
# ... previous steps ...
COPY docker-entrypoint.sh ./
RUN chmod +x docker-entrypoint.sh
CMD ["./docker-entrypoint.sh"]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 matches your local environment
- All dependencies are properly installed
- Database connection is available during build (if needed for migrations)