From 9f3f5c9e5519df26d9c94d3ecc4495e98ff508c6 Mon Sep 17 00:00:00 2001 From: laobinghu <923190468@qq.com> Date: Sat, 28 Mar 2026 17:01:29 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEPLOY.md | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 DEPLOY.md diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..76b8b23 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,396 @@ +# 部署文档 + +## 项目概览 + +**技术栈:** Nuxt 4 + Nuxt UI + Pinia + ofetch + +**构建产物:** SSR 模式,生成 `.output` 目录(包含 Node.js 服务器) + +--- + +## 一、构建前准备 + +### 1.1 环境变量配置 + +复制 `.env.example` 为 `.env`: + +```bash +cp .env.example .env +``` + +编辑 `.env` 文件: + +```env +# API 后端地址 +NUXT_PUBLIC_API_BASE=https://api.yourdomain.com + +# 站点地址 +NUXT_PUBLIC_SITE_URL=https://yourdomain.com +NUXT_PUBLIC_SITE_NAME=LinkShare Blog +``` + +--- + +## 二、构建应用 + +### 2.1 安装依赖并构建 + +```bash +# 安装依赖 +pnpm install + +# 构建生产版本 +pnpm run build +``` + +构建产物位于 `.output/` 目录: + +``` +.output/ +├── public/ # 静态资源 +├── server/ # Node.js 服务器 +│ └── index.mjs # 入口文件 +└── server/ + └── index.mjs +``` + +### 2.2 本地预览 + +```bash +# 构建后本地测试 +pnpm run preview +``` + +--- + +## 三、部署方案 + +### 方案 1:直接部署(推荐) + +**适用场景:** 支持 SSR 的服务器环境 + +**启动命令:** + +```bash +# 设置环境变量 +export NUXT_PUBLIC_API_BASE="https://api.yourdomain.com" +export NUXT_PUBLIC_SITE_URL="https://yourdomain.com" +export NUXT_PUBLIC_SITE_NAME="LinkShare Blog" + +# 启动服务器 +node .output/server/index.mjs +``` + +**使用 PM2 管理进程:** + +```bash +# 安装 PM2 +npm install -g pm2 + +# 启动应用 +pm2 start .output/server/index.mjs --name "binglogy-blog" -- \ + --env production + +# 查看状态 +pm2 status + +# 查看日志 +pm2 logs binglogy-blog + +# 设置开机自启 +pm2 save +pm2 startup +``` + +**PM2 配置文件(ecosystem.config.js):** + +```javascript +module.exports = { + apps: [{ + name: 'binglogy-blog', + script: '.output/server/index.mjs', + instances: 'max', + exec_mode: 'cluster', + env: { + NODE_ENV: 'production', + NUXT_PUBLIC_API_BASE: 'https://api.yourdomain.com', + NUXT_PUBLIC_SITE_URL: 'https://yourdomain.com', + NUXT_PUBLIC_SITE_NAME: 'LinkShare Blog', + PORT: 3000 + } + }] +} +``` + +使用配置文件启动: + +```bash +pm2 start ecosystem.config.js +``` + +--- + +### 方案 2:Docker 部署 + +**Dockerfile:** + +```dockerfile +# 构建阶段 +FROM node:20-alpine AS builder + +WORKDIR /app + +# 安装 pnpm +RUN npm install -g pnpm + +# 安装依赖 +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +# 构建应用 +COPY . . +RUN pnpm run build + +# 生产阶段 +FROM node:20-alpine + +WORKDIR /app + +# 设置环境变量 +ENV NODE_ENV=production + +# 复制构建产物 +COPY --from=builder /app/.output ./.output +COPY --from=builder /app/public ./public + +# 暴露端口 +EXPOSE 3000 + +# 启动服务器 +CMD ["node", ".output/server/index.mjs"] +``` + +**docker-compose.yml:** + +```yaml +version: '3.8' + +services: + frontend: + build: . + container_name: binglogy-blog + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - NUXT_PUBLIC_API_BASE=https://api.yourdomain.com + - NUXT_PUBLIC_SITE_URL=https://yourdomain.com + - NUXT_PUBLIC_SITE_NAME=LinkShare Blog + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/"] + interval: 30s + timeout: 10s + retries: 3 + networks: + - binglogy + +networks: + binglogy: + driver: bridge +``` + +**构建和启动:** + +```bash +# 构建镜像 +docker compose build + +# 启动服务 +docker compose up -d + +# 查看日志 +docker compose logs -f + +# 停止服务 +docker compose down +``` + +--- + +### 方案 3:Nginx 反向代理 + +**适用场景:** 生产环境,配合 Nginx 使用 + +**Nginx 配置:** + +```nginx +server { + listen 80; + server_name yourdomain.com; + + # HTTPS 重定向 + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name yourdomain.com; + + # SSL 证书 + ssl_certificate /etc/nginx/ssl/yourdomain.com.pem; + ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + # Gzip 压缩 + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; + + # 静态资源缓存 + location /_nuxt/ { + alias /path/to/.output/public/_nuxt/; + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # 其他静态文件 + location /static/ { + alias /path/to/.output/public/static/; + expires 30d; + add_header Cache-Control "public"; + } + + # 代理到 Nuxt + location / { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + 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; + proxy_cache_bypass $http_upgrade; + } + + # 错误页面 + error_page 404 /404.html; + error_page 500 502 503 504 /50x.html; +} +``` + +--- + +## 四、路由规则配置 + +项目已配置以下路由规则(nuxt.config.ts): + +```typescript +nitro: { + routeRules: { + '/': { isr: 60 }, // 首页每60秒重新验证 + '/article/**': { isr: 300 }, // 文章页每300秒重新验证 + '/admin/**': { ssr: false }, // 管理后台纯客户端渲染 + }, +} +``` + +--- + +## 五、环境变量说明 + +| 变量名 | 说明 | 默认值 | 必填 | +|-------|------|-------|-----| +| NUXT_PUBLIC_API_BASE | 后端 API 地址 | http://localhost:3001 | 是 | +| NUXT_PUBLIC_SITE_URL | 站点 URL | http://localhost:3000 | 否 | +| NUXT_PUBLIC_SITE_NAME | 站点名称 | LinkShare Blog | 否 | +| PORT | 服务端口 | 3000 | 否 | + +--- + +## 六、常见问题 + +### 6.1 启动报错 "Cannot find module" + +**原因:** 构建产物未正确复制 + +**解决:** 确保 `.output` 目录完整,运行 `pnpm run build` 重新构建 + +### 6.2 API 请求跨域 + +**原因:** 后端 CORS 配置不正确 + +**解决:** 后端需允许前端域名,建议使用 Nginx 反向代理,前端和后端同源 + +### 6.3 页面加载慢 + +**原因:** SSR 首次渲染较慢 + +**解决:** +- 调整 ISR 缓存时间(nuxt.config.ts 中的 routeRules) +- 使用 CDN 加速静态资源 +- 启用 Nginx Gzip 压缩 + +### 6.4 内存占用过高 + +**原因:** Node.js 默认内存限制 + +**解决:** +```bash +node --max-old-space-size=4096 .output/server/index.mjs +``` + +--- + +## 七、生产环境检查清单 + +- [ ] 环境变量已正确配置 +- [ ] 后端 API 地址正确 +- [ ] SSL 证书已配置(HTTPS) +- [ ] Nginx 反向代理已配置 +- [ ] Gzip 压缩已启用 +- [ ] 静态资源缓存策略已设置 +- [ ] 进程管理工具已配置(PM2/Docker) +- [ ] 错误监控已配置(可选) + +--- + +## 八、监控和日志 + +### 8.1 PM2 日志 + +```bash +# 实时日志 +pm2 logs binglogy-blog --lines 100 + +# 错误日志 +pm2 logs binglogy-blog --err + +# 日志文件位置 +~/.pm2/logs/ +``` + +### 8.2 Docker 日志 + +```bash +# 实时日志 +docker logs -f binglogy-blog + +# 最近100行 +docker logs --tail 100 binglogy-blog +``` + +### 8.3 Nginx 日志 + +```bash +# 访问日志 +tail -f /var/log/nginx/access.log + +# 错误日志 +tail -f /var/log/nginx/error.log +```