476 lines
8.8 KiB
Markdown
476 lines
8.8 KiB
Markdown
# 部署文档
|
||
|
||
## 部署概述
|
||
|
||
项目采用 Next.js 静态导出模式,构建生成纯静态 HTML 文件,可部署到任何静态文件服务器或 CDN。
|
||
|
||
## 构建配置
|
||
|
||
### Next.js 配置
|
||
|
||
```typescript
|
||
// next.config.ts
|
||
const nextConfig: NextConfig = {
|
||
output: 'export', // 静态导出模式
|
||
distDir: 'dist', // 输出目录
|
||
images: {
|
||
unoptimized: true, // 静态导出需要禁用图片优化
|
||
},
|
||
compress: true,
|
||
poweredByHeader: false,
|
||
reactStrictMode: true,
|
||
};
|
||
```
|
||
|
||
### 构建命令
|
||
|
||
```bash
|
||
# 开发模式(不导出)
|
||
npm run dev
|
||
|
||
# 生产构建(静态导出)
|
||
npm run build
|
||
|
||
# 输出目录
|
||
dist/
|
||
```
|
||
|
||
## 环境变量
|
||
|
||
### 必需配置
|
||
|
||
```env
|
||
# .env.production
|
||
RESEND_API_KEY=re_xxxxx
|
||
COMPANY_EMAIL=contact@novalon.cn
|
||
```
|
||
|
||
### 可选配置
|
||
|
||
```env
|
||
NODE_ENV=production
|
||
NEXT_PUBLIC_SITE_URL=https://www.novalon.cn
|
||
```
|
||
|
||
### 环境变量说明
|
||
|
||
| 变量名 | 必需 | 描述 |
|
||
|--------|------|------|
|
||
| `RESEND_API_KEY` | 是 | Resend 邮件服务 API 密钥 |
|
||
| `COMPANY_EMAIL` | 是 | 公司接收邮件的邮箱地址 |
|
||
| `NODE_ENV` | 否 | 环境标识 |
|
||
| `NEXT_PUBLIC_SITE_URL` | 否 | 网站公开 URL |
|
||
|
||
## 部署平台
|
||
|
||
### 1. Vercel 部署(推荐)
|
||
|
||
**优势:**
|
||
- 零配置部署
|
||
- 自动 HTTPS
|
||
- 全球 CDN
|
||
- 预览部署
|
||
- 边缘函数支持
|
||
|
||
**部署步骤:**
|
||
|
||
1. 连接 Git 仓库
|
||
2. 配置环境变量
|
||
3. 部署设置:
|
||
- Build Command: `npm run build`
|
||
- Output Directory: `dist`
|
||
- Install Command: `npm install`
|
||
|
||
**vercel.json 配置:**
|
||
|
||
```json
|
||
{
|
||
"buildCommand": "npm run build",
|
||
"outputDirectory": "dist",
|
||
"framework": "nextjs",
|
||
"regions": ["hkg1"]
|
||
}
|
||
```
|
||
|
||
### 2. 静态文件服务器部署
|
||
|
||
**适用场景:**
|
||
- Nginx
|
||
- Apache
|
||
- IIS
|
||
- 云存储(阿里云 OSS、腾讯云 COS)
|
||
|
||
**Nginx 配置示例:**
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name www.novalon.cn novalon.cn;
|
||
root /var/www/novalon-website/dist;
|
||
index index.html;
|
||
|
||
# 强制 HTTPS
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name www.novalon.cn novalon.cn;
|
||
root /var/www/novalon-website/dist;
|
||
index index.html;
|
||
|
||
# SSL 证书
|
||
ssl_certificate /etc/nginx/ssl/novalon.cn.pem;
|
||
ssl_certificate_key /etc/nginx/ssl/novalon.cn.key;
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||
ssl_prefer_server_ciphers off;
|
||
|
||
# 安全头部
|
||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||
add_header X-Content-Type-Options "nosniff" always;
|
||
add_header X-XSS-Protection "1; mode=block" always;
|
||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" always;
|
||
|
||
# Gzip 压缩
|
||
gzip on;
|
||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||
gzip_min_length 1000;
|
||
|
||
# 静态资源缓存
|
||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||
expires 1y;
|
||
add_header Cache-Control "public, immutable";
|
||
}
|
||
|
||
# HTML 不缓存
|
||
location ~* \.html$ {
|
||
expires -1;
|
||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||
}
|
||
|
||
# SPA 路由支持
|
||
location / {
|
||
try_files $uri $uri.html $uri/ =404;
|
||
}
|
||
|
||
# 404 页面
|
||
error_page 404 /404.html;
|
||
}
|
||
```
|
||
|
||
### 3. Docker 部署
|
||
|
||
**Dockerfile:**
|
||
|
||
```dockerfile
|
||
# 构建阶段
|
||
FROM node:18-alpine AS builder
|
||
|
||
WORKDIR /app
|
||
|
||
COPY package*.json ./
|
||
RUN npm ci
|
||
|
||
COPY . .
|
||
RUN npm run build
|
||
|
||
# 运行阶段
|
||
FROM nginx:alpine
|
||
|
||
# 复制构建产物
|
||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||
|
||
# 复制 Nginx 配置
|
||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||
|
||
EXPOSE 80
|
||
|
||
CMD ["nginx", "-g", "daemon off;"]
|
||
```
|
||
|
||
**构建和运行:**
|
||
|
||
```bash
|
||
# 构建镜像
|
||
docker build -t novalon-website .
|
||
|
||
# 运行容器
|
||
docker run -d -p 80:80 --name novalon novalon-website
|
||
```
|
||
|
||
### 4. 云存储部署
|
||
|
||
**阿里云 OSS:**
|
||
|
||
1. 创建 OSS Bucket
|
||
2. 配置静态网站托管
|
||
3. 上传 `dist/` 目录内容
|
||
4. 配置自定义域名
|
||
5. 配置 HTTPS 证书
|
||
|
||
**腾讯云 COS:**
|
||
|
||
1. 创建 COS Bucket
|
||
2. 开启静态网站功能
|
||
3. 上传构建产物
|
||
4. 配置 CDN 加速
|
||
|
||
## CI/CD 流水线
|
||
|
||
### Woodpecker CI 配置
|
||
|
||
```yaml
|
||
# .woodpecker.yml
|
||
pipeline:
|
||
install:
|
||
image: node:18-alpine
|
||
commands:
|
||
- npm ci
|
||
when:
|
||
event:
|
||
- push
|
||
- pull_request
|
||
|
||
lint:
|
||
image: node:18-alpine
|
||
commands:
|
||
- npm run lint
|
||
when:
|
||
event:
|
||
- push
|
||
- pull_request
|
||
|
||
build:
|
||
image: node:18-alpine
|
||
environment:
|
||
NODE_ENV: production
|
||
commands:
|
||
- npm run build
|
||
when:
|
||
event:
|
||
- push
|
||
branch:
|
||
- main
|
||
|
||
e2e-tests:
|
||
image: node:18-alpine
|
||
environment:
|
||
NODE_ENV: test
|
||
CI: true
|
||
commands:
|
||
- cd e2e
|
||
- npm ci
|
||
- npx playwright install --with-deps chromium
|
||
- npm run test:smoke
|
||
when:
|
||
event:
|
||
- push
|
||
- pull_request
|
||
|
||
deploy:
|
||
image: node:18-alpine
|
||
commands:
|
||
- npm install -g vercel
|
||
- vercel --prod --token=$VERCEL_TOKEN
|
||
secrets:
|
||
- vercel_token
|
||
when:
|
||
event:
|
||
- push
|
||
branch:
|
||
- main
|
||
```
|
||
|
||
## 部署检查清单
|
||
|
||
### 部署前检查
|
||
|
||
- [ ] 环境变量已配置
|
||
- [ ] 构建成功无错误
|
||
- [ ] E2E 测试通过
|
||
- [ ] ESLint 检查通过
|
||
- [ ] 图片资源已优化
|
||
- [ ] 死链检查通过
|
||
|
||
### 部署后验证
|
||
|
||
- [ ] 首页正常加载
|
||
- [ ] 所有页面可访问
|
||
- [ ] 表单提交正常
|
||
- [ ] 移动端适配正常
|
||
- [ ] HTTPS 证书有效
|
||
- [ ] 性能指标达标
|
||
- [ ] SEO 元数据正确
|
||
|
||
### 性能指标
|
||
|
||
| 指标 | 目标值 |
|
||
|------|--------|
|
||
| LCP | < 2.5s |
|
||
| FID | < 100ms |
|
||
| CLS | < 0.1 |
|
||
| TTFB | < 600ms |
|
||
| 首屏加载 | < 3s |
|
||
|
||
## 回滚策略
|
||
|
||
### Vercel 回滚
|
||
|
||
```bash
|
||
# 列出部署历史
|
||
vercel ls
|
||
|
||
# 回滚到指定版本
|
||
vercel rollback [deployment-url]
|
||
```
|
||
|
||
### 静态服务器回滚
|
||
|
||
```bash
|
||
# 保留历史版本
|
||
/var/www/novalon-website/
|
||
├── current -> releases/20260307-1
|
||
├── releases/
|
||
│ ├── 20260307-1/
|
||
│ ├── 20260306-1/
|
||
│ └── 20260305-1/
|
||
└── shared/
|
||
|
||
# 回滚操作
|
||
ln -sfn releases/20260306-1 current
|
||
```
|
||
|
||
## 监控与告警
|
||
|
||
### 推荐工具
|
||
|
||
| 工具 | 用途 |
|
||
|------|------|
|
||
| Vercel Analytics | 性能监控 |
|
||
| Sentry | 错误监控 |
|
||
| Uptime Robot | 可用性监控 |
|
||
| Google Search Console | SEO 监控 |
|
||
|
||
### 告警配置
|
||
|
||
```yaml
|
||
# Uptime Robot 配置示例
|
||
monitors:
|
||
- name: Novalon Website
|
||
url: https://www.novalon.cn
|
||
type: https
|
||
interval: 300
|
||
alert_contacts:
|
||
- email: admin@novalon.cn
|
||
```
|
||
|
||
## 安全配置
|
||
|
||
### 安全头部
|
||
|
||
```http
|
||
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
|
||
X-Frame-Options: SAMEORIGIN
|
||
X-Content-Type-Options: nosniff
|
||
X-XSS-Protection: 1; mode=block
|
||
Referrer-Policy: strict-origin-when-cross-origin
|
||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;
|
||
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
||
```
|
||
|
||
### HTTPS 配置
|
||
|
||
- 使用 TLS 1.2 或更高版本
|
||
- 配置 HSTS
|
||
- 启用 OCSP Stapling
|
||
- 使用强加密套件
|
||
|
||
## 性能优化
|
||
|
||
### 构建优化
|
||
|
||
1. **代码分割**
|
||
- 动态导入非首屏组件
|
||
- 路由级别分割
|
||
|
||
2. **资源优化**
|
||
- 图片压缩和格式转换
|
||
- CSS 压缩
|
||
- JavaScript 压缩
|
||
|
||
3. **缓存策略**
|
||
- 静态资源长缓存
|
||
- HTML 不缓存
|
||
- API 响应适当缓存
|
||
|
||
### CDN 配置
|
||
|
||
```
|
||
# CDN 缓存规则
|
||
*.js, *.css -> 缓存 1 年
|
||
*.jpg, *.png -> 缓存 1 年
|
||
*.woff, *.woff2 -> 缓存 1 年
|
||
*.html -> 不缓存
|
||
```
|
||
|
||
## 故障排查
|
||
|
||
### 常见问题
|
||
|
||
**1. 页面 404 错误**
|
||
- 检查静态文件是否正确上传
|
||
- 检查 Nginx 配置的 root 路径
|
||
- 检查 SPA 路由配置
|
||
|
||
**2. 样式加载失败**
|
||
- 检查 CSS 文件路径
|
||
- 检查 Content-Security-Policy 配置
|
||
- 清除浏览器缓存
|
||
|
||
**3. 表单提交失败**
|
||
- 检查 API 路由是否正常
|
||
- 检查环境变量配置
|
||
- 检查 CORS 配置
|
||
|
||
**4. 性能问题**
|
||
- 检查图片是否优化
|
||
- 检查 CDN 是否生效
|
||
- 检查服务器响应时间
|
||
|
||
### 日志查看
|
||
|
||
```bash
|
||
# Nginx 访问日志
|
||
tail -f /var/log/nginx/access.log
|
||
|
||
# Nginx 错误日志
|
||
tail -f /var/log/nginx/error.log
|
||
|
||
# Vercel 日志
|
||
vercel logs [deployment-url]
|
||
```
|
||
|
||
## 维护计划
|
||
|
||
### 定期任务
|
||
|
||
| 任务 | 频率 |
|
||
|------|------|
|
||
| 依赖更新 | 每月 |
|
||
| 安全扫描 | 每周 |
|
||
| 性能测试 | 每周 |
|
||
| 备份验证 | 每月 |
|
||
| SSL 证书更新 | 到期前 30 天 |
|
||
|
||
### 更新流程
|
||
|
||
1. 创建更新分支
|
||
2. 执行依赖更新
|
||
3. 运行测试套件
|
||
4. 部署到预览环境
|
||
5. 验证功能正常
|
||
6. 合并到主分支
|
||
7. 自动部署到生产环境
|