乐闻世界logo
搜索文章和话题

Next.js 如何部署到生产环境?

2月17日 23:32

Next.js 提供了多种部署选项,开发者可以根据项目需求选择最适合的部署方式。以下是 Next.js 的主要部署选项和最佳实践:

1. Vercel(推荐)

Vercel 是 Next.js 的创建者提供的托管平台,提供最佳的 Next.js 部署体验。

优点

  • 零配置部署
  • 自动 HTTPS
  • 全球 CDN
  • 边缘函数支持
  • 预览部署
  • 自动优化

部署步骤

bash
# 1. 安装 Vercel CLI npm i -g vercel # 2. 登录 Vercel vercel login # 3. 部署 vercel # 4. 生产环境部署 vercel --prod

配置文件

javascript
// vercel.json { "buildCommand": "npm run build", "outputDirectory": ".next", "framework": "nextjs", "regions": ["iad1"], "functions": { "app/api/**/*.js": { "maxDuration": 30 } }, "headers": [ { "source": "/(.*)", "headers": [ { "key": "X-Content-Type-Options", "value": "nosniff" }, { "key": "X-Frame-Options", "value": "DENY" } ] } ] }

2. 自托管(Docker)

使用 Docker 容器化 Next.js 应用,部署到任何支持 Docker 的平台。

Dockerfile

dockerfile
# 多阶段构建 FROM node:18-alpine AS base # 依赖阶段 FROM base AS deps WORKDIR /app COPY package.json package-lock.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 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs 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 USER nextjs EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME "0.0.0.0" CMD ["node", "server.js"]

docker-compose.yml

yaml
version: '3.8' services: nextjs: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=${DATABASE_URL} restart: unless-stopped

构建和运行

bash
# 构建镜像 docker build -t nextjs-app . # 运行容器 docker run -p 3000:3000 nextjs-app # 使用 docker-compose docker-compose up -d

3. Node.js 服务器

将 Next.js 应用部署到传统的 Node.js 服务器。

使用 PM2

javascript
// ecosystem.config.js module.exports = { apps: [{ name: 'nextjs-app', script: 'node_modules/next/dist/bin/next', args: 'start -p 3000', instances: 'max', exec_mode: 'cluster', env: { NODE_ENV: 'production', PORT: 3000 }, error_file: './logs/err.log', out_file: './logs/out.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z' }] };
bash
# 安装 PM2 npm install -g pm2 # 启动应用 pm2 start ecosystem.config.js # 查看状态 pm2 status # 查看日志 pm2 logs # 重启应用 pm2 restart nextjs-app

使用 Nginx 反向代理

nginx
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; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

4. 静态导出

对于不需要服务器端功能的简单应用,可以导出为静态 HTML。

配置

javascript
// next.config.js module.exports = { output: 'export', images: { unoptimized: true } };

构建和部署

bash
# 构建 npm run build # 输出在 out/ 目录 # 可以部署到任何静态托管服务,如: # - GitHub Pages # - Netlify # - AWS S3 + CloudFront # - Firebase Hosting

5. 云平台部署

AWS

使用 AWS Amplify

bash
# 安装 Amplify CLI npm install -g @aws-amplify/cli # 初始化 amplify init # 添加托管 amplify add hosting # 发布 amplify publish

使用 AWS Lambda

javascript
// app/api/hello/route.js export const runtime = 'edge'; export async function GET() { return Response.json({ message: 'Hello from Edge!' }); }

Google Cloud

使用 Cloud Run

bash
# 构建镜像 gcloud builds submit --tag gcr.io/PROJECT_ID/nextjs-app # 部署到 Cloud Run gcloud run deploy nextjs-app \ --image gcr.io/PROJECT_ID/nextjs-app \ --platform managed \ --region us-central1 \ --allow-unauthenticated

Azure

使用 Azure Static Web Apps

bash
# 安装 Azure CLI npm install -g @azure/static-web-apps-cli # 部署 swa deploy ./out --env production

6. CI/CD 集成

GitHub Actions

yaml
name: Deploy to Vercel on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm test - name: Build run: npm run build - name: Deploy to Vercel uses: amondnet/vercel-action@v20 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.ORG_ID }} vercel-project-id: ${{ secrets.PROJECT_ID }} vercel-args: '--prod'

GitLab CI

yaml
image: node:18 stages: - test - build - deploy test: stage: test script: - npm ci - npm test build: stage: build script: - npm ci - npm run build artifacts: paths: - .next/ deploy: stage: deploy script: - npm install -g vercel - vercel --prod --token=$VERCEL_TOKEN only: - main

环境变量管理

.env 文件

bash
# .env.local(本地开发) DATABASE_URL=postgresql://localhost/mydb API_KEY=your_api_key # .env.production(生产环境) DATABASE_URL=postgresql://prod-db-host/mydb API_KEY=prod_api_key

Vercel 环境变量

bash
# 使用 Vercel CLI vercel env add DATABASE_URL production # 或在 Vercel Dashboard 中设置

性能优化

1. 启用压缩

javascript
// next.config.js module.exports = { compress: true, };

2. 优化图片

javascript
// next.config.js module.exports = { images: { formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200, 1920], }, };

3. 启用 SWC 压缩

javascript
// next.config.js module.exports = { swcMinify: true, };

监控和日志

使用 Vercel Analytics

javascript
// pages/_app.js import { Analytics } from '@vercel/analytics/react'; export default function App({ Component, pageProps }) { return ( <> <Component {...pageProps} /> <Analytics /> </> ); }

使用 Sentry

javascript
// sentry.client.config.js import * as Sentry from '@sentry/nextjs'; Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, tracesSampleRate: 1.0, });

部署最佳实践

  1. 使用 Vercel:获得最佳的 Next.js 部署体验
  2. 环境变量:使用 .env 文件管理环境变量
  3. CI/CD:设置自动部署流程
  4. 监控:使用监控工具跟踪应用性能
  5. 备份:定期备份数据库和重要文件
  6. 测试:部署前运行完整的测试套件
  7. 渐进式部署:使用蓝绿部署或金丝雀发布
  8. 文档化:记录部署流程和配置

通过合理选择部署方式和遵循最佳实践,可以确保 Next.js 应用稳定、高效地运行在生产环境中。

标签:Next.js