Next.js Build and Deployment

Overview

Next.js supports multiple deployment options, including Vercel, self-hosted servers, Docker, and more.

Building the Application

Production Build

npm run build
npm run start

Build Output

.next/
  ├── cache/          # 构建缓存
  ├── server/         # 服务端代码
  ├── static/         # 静态资源
  └── standalone/     # 独立部署文件

Vercel Deployment

Automatic Deployment

  1. Push code to GitHub
  2. Import the project on Vercel
  3. Automatic build and deployment

Environment Variables

# Vercel Dashboard
DATABASE_URL=postgresql://...
JWT_SECRET=your-secret

Docker Deployment

Dockerfile

FROM node:18-alpine AS base

# 依赖阶段
FROM base AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# 构建阶段
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 运行阶段
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production

COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

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

docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://...
    depends_on:
      - db
  
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Self-Hosted Deployment

PM2

npm install -g pm2
pm2 start npm --name "nextjs-app" -- start
pm2 save
pm2 startup

Nginx Configuration

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Performance Optimization

next.config.js

module.exports = {
  output: 'standalone',
  compress: true,
  images: {
    domains: ['example.com'],
    formats: ['image/avif', 'image/webp'],
  },
  experimental: {
    optimizeCss: true,
  },
}

Best Practices

1. Environment Variables

# .env.production
DATABASE_URL=production-url
API_URL=https://api.example.com

2. Health Checks

// app/api/health/route.ts
export async function GET() {
  return Response.json({ status: 'ok' })
}

3. Logging

// lib/logger.ts
export function log(message: string, data?: any) {
  if (process.env.NODE_ENV === 'production') {
    // 发送到日志服务
  } else {
    console.log(message, data)
  }
}

Previous Chapter: Next.js Security Best Practices | Next Chapter: Next.js Vercel Deployment