部署平台
如何选择部署平台?
| 需求 | 推荐平台 | 理由 |
|---|---|---|
| 快速上线、免费起步 | Vercel | 零配置,Git 推送即部署,免费额度大 |
| 国内用户为主 | 阿里云/腾讯云 + Node.js | 国内 CDN 加速,合规性好 |
| 全栈 SSR + API | Node.js / Docker | 完全控制,适合复杂后端逻辑 |
| 边缘计算、全球加速 | Cloudflare Pages | 全球边缘节点,延迟低 |
| 纯静态站点 | Netlify / GitHub Pages | 零运维,免费额度大 |
| 企业级稳定性 | Docker + K8s | 可控、可扩展、可迁移 |
决策原则
个人项目/ MVP 先用 Vercel 快速验证,有用户后再考虑迁移到自建服务器。企业项目根据合规和运维能力选择。
Node.js 部署
最通用的部署方式,适合所有 Nuxt 渲染模式(SSR/SSG/Hybrid):
# 构建
npx nuxt build
# 运行
node .output/server/index.mjs为什么用 Node.js?
它是 Nuxt 的默认预设,支持所有功能(SSR、API 路由、服务端中间件等),不需要适配特定的云平台 API。适合需要完全控制运行环境的场景。
PM2 进程管理
为什么需要 PM2?
直接用 node 运行,进程崩溃后不会自动重启,也不支持集群模式。PM2 提供进程守护、自动重启、负载均衡、日志管理等功能。
npm install -g pm2创建配置文件:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'my-nuxt-app',
script: '.output/server/index.mjs',
instances: 'max', // 根据 CPU 核心数自动创建实例
exec_mode: 'cluster', // 集群模式
env: {
NODE_ENV: 'production',
PORT: 3000,
},
}],
}# 启动
pm2 start ecosystem.config.js
# 常用命令
pm2 list # 查看所有进程
pm2 logs my-nuxt-app # 查看日志
pm2 restart my-nuxt-app # 重启
pm2 stop my-nuxt-app # 停止
pm2 monit # 监控面板
# 开机自启动
pm2 startup
pm2 save集群模式
也可以通过 Nitro 预设启用:
export default defineNuxtConfig({
nitro: {
preset: 'node-cluster',
},
})Vercel
为什么选 Vercel?
零配置部署、Git 推送自动构建、预览环境(每个 PR 自动生成预览 URL)、Serverless 函数自动扩缩容、免费额度充足(个人项目几乎零成本)。
export default defineNuxtConfig({
nitro: {
preset: 'vercel',
},
})部署步骤
- 将代码推送到 GitHub/GitLab
- 在 vercel.com 导入项目
- Vercel 自动检测 Nuxt 框架并配置构建命令
- 环境变量在 Vercel 控制台的 Settings → Environment Variables 中配置
- 每次推送代码自动触发部署
INFO
️ Vercel 的限制: Serverless 函数有执行时间限制(免费版 10 秒) 长时间运行的任务(如大文件处理)不适合。函数大小限制 50MB,如果 .output 过大需要优化
Netlify
export default defineNuxtConfig({
nitro: {
preset: 'netlify',
},
})部署方式与 Vercel 类似,连接 Git 仓库后自动部署。适合静态站点和轻量级 SSR。
Cloudflare Pages
为什么选 Cloudflare?
全球 300+ 边缘节点,延迟极低。Workers 免费额度大(每天 10 万次请求),适合流量较大的项目。
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages',
},
})wrangler.toml
name = "my-nuxt-app"
compatibility_date = "2025-01-01"INFO
️ Cloudflare Workers 的限制: 单次请求执行时间限制 10ms(免费版)/ 30ms(付费版) 代码大小限制 1MB(免费版)。不适合计算密集型任务。compatibility_date 用于指定运行时 API 版本,建议设为近期日期
Deno Deploy
export default defineNuxtConfig({
nitro: {
preset: 'deno-deploy',
},
})适合边缘计算场景,全球分布式部署。
Docker 部署
为什么用 Docker?
环境一致性(开发、测试、生产完全相同)、方便 CI/CD 集成、易于迁移到任何云平台。适合团队协作和企业项目。
Dockerfile
# 阶段一:构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 阶段二:运行
FROM node:20-alpine
WORKDIR /app
# 安全:使用非 root 用户
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
COPY --from=builder /app/.output .output
USER appuser
EXPOSE 3000
ENV HOST=0.0.0.0
ENV PORT=3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
CMD ["node", ".output/server/index.mjs"].dockerignore
node_modules
.nuxt
.output
.git
*.md为什么用多阶段构建?
构建阶段需要 node_modules(几百MB),但运行阶段只需要 .output(几MB)。多阶段构建让最终镜像更小、更安全(不包含源码和开发依赖)。
Docker Compose
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NUXT_PUBLIC_API_BASE=https://api.example.com
restart: unless-stoppeddocker compose up -d # 启动
docker compose logs -f # 查看日志
docker compose down # 停止静态托管
适用场景
纯内容站点(博客、文档、落地页),不需要服务端渲染和 API 路由。成本最低,性能最好。
npx nuxt generate将 .output/public/ 部署到:
| 平台 | 特点 | 免费额度 |
|---|---|---|
| GitHub Pages | Git 推送自动部署 | 无限 |
| Netlify | 自动 HTTPS,表单处理 | 100GB/月 |
| AWS S3 + CloudFront | 企业级,全球 CDN | 按用量 |
| 阿里云 OSS + CDN | 国内加速好 | 按用量 |
| 腾讯云 COS + CDN | 国内加速好 | 按用量 |
INFO
️ SPA 路由的 404 问题: 静态托管时 直接访问 /about 会返回 404,因为服务器找不到对应的文件。需要配置所有路由都返回 index.html,让前端路由处理。各平台配置方式不同,GitHub Pages 需要 404.html,Netlify 需要 _redirects 文件
部署检查清单
- [ ] 环境变量已配置(检查
runtimeConfig中的敏感信息) - [ ] 数据库连接正常(使用生产环境配置)
- [ ] HTTPS 已启用(Let's Encrypt 免费证书)
- [ ] CORS 配置正确(只允许需要的域名)
- [ ] 静态资源 CDN 配置(图片、CSS、JS 加速)
- [ ] 日志收集已配置(PM2 日志 / 云平台日志 / ELK)
- [ ] 错误监控已接入(Sentry / 自建监控)
- [ ] 备份策略已实施(数据库定时备份、配置文件版本管理)
- [ ] 健康检查接口可用(
/api/health) - [ ]
.output/未提交到 Git(应加入.gitignore)
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Vercel 部署后 API 路由超时 | Serverless 函数执行时间限制 | 优化 API 性能,或改用 Node.js 部署 |
| Docker 镜像过大 | 没有用多阶段构建 | 使用上面的多阶段 Dockerfile |
| 静态站点子路由 404 | 服务器未配置 SPA 回退 | 配置所有路由返回 index.html |
| PM2 启动后立即崩溃 | 环境变量缺失或端口冲突 | 检查 pm2 logs 排查具体错误 |
| Cloudflare 部署失败 | Worker 大小超限 | 检查 .output 大小,优化依赖 |
| Node.js 部署内存溢出 | 默认堆内存不足 | 启动时设置 NODE_OPTIONS=--max-old-space-size=4096 |