Files
admin-vben/docs/部署文档.md

768 lines
14 KiB
Markdown
Raw Normal View History

# 部署文档
## 部署概述
AIOTAGRO 管理系统支持多种部署方式,包括开发环境部署、测试环境部署和生产环境部署。本文档详细说明各种部署场景的配置和步骤。
## 环境要求
### 服务器要求
| 环境 | CPU | 内存 | 磁盘 | 网络 |
|------|-----|------|------|------|
| 开发环境 | 2核 | 4GB | 20GB | 10Mbps |
| 测试环境 | 4核 | 8GB | 50GB | 50Mbps |
| 生产环境 | 8核 | 16GB | 100GB | 100Mbps |
### 软件要求
| 软件 | 版本 | 说明 |
|------|------|------|
| Node.js | 18.0.0+ | JavaScript 运行时 |
| pnpm | 8.0.0+ | 包管理器 |
| Nginx | 1.20.0+ | Web 服务器 |
| Git | 2.30.0+ | 版本控制 |
## 开发环境部署
### 本地开发环境
#### 1. 环境准备
```bash
# 安装 Node.js
# 访问 https://nodejs.org/ 下载安装包
# 安装 pnpm
npm install -g pnpm
# 验证安装
node --version
pnpm --version
```
#### 2. 项目初始化
```bash
# 克隆项目
git clone https://github.com/aiotagro/yudao-ui-admin-vben.git
cd yudao-ui-admin-vben
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev:antd
```
#### 3. 访问应用
打开浏览器访问: http://localhost:3000
### Docker 开发环境
#### 1. Dockerfile 配置
```dockerfile
# Dockerfile.dev
FROM node:18-alpine
WORKDIR /app
# 复制 package.json 和 pnpm-lock.yaml
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN npm install -g pnpm && pnpm install
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动开发服务器
CMD ["pnpm", "dev:antd"]
```
#### 2. docker-compose 配置
```yaml
# docker-compose.dev.yml
version: '3.8'
services:
frontend:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
```
#### 3. 启动服务
```bash
# 构建并启动服务
docker-compose -f docker-compose.dev.yml up --build
# 后台运行
docker-compose -f docker-compose.dev.yml up -d
```
## 测试环境部署
### 手动部署
#### 1. 服务器准备
```bash
# 登录服务器
ssh user@test-server
# 创建项目目录
mkdir -p /opt/aiotagro/frontend
cd /opt/aiotagro/frontend
# 克隆代码
git clone https://github.com/aiotagro/yudao-ui-admin-vben.git .
```
#### 2. 环境配置
```bash
# 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# 安装 pnpm
npm install -g pnpm
# 安装依赖
pnpm install
```
#### 3. 构建应用
```bash
# 构建生产版本
pnpm build:antd
# 检查构建结果
ls -la dist/
```
#### 4. 配置 Nginx
```nginx
# /etc/nginx/sites-available/aiotagro-test
server {
listen 80;
server_name test.aiotagro.com;
root /opt/aiotagro/frontend/dist;
index index.html;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# API 代理
location /api/ {
proxy_pass http://backend-server:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
#### 5. 启用站点
```bash
# 创建符号链接
sudo ln -s /etc/nginx/sites-available/aiotagro-test /etc/nginx/sites-enabled/
# 测试配置
sudo nginx -t
# 重启 Nginx
sudo systemctl restart nginx
```
### 自动化部署脚本
```bash
#!/bin/bash
# deploy-test.sh
set -e
# 配置变量
PROJECT_DIR="/opt/aiotagro/frontend"
BACKUP_DIR="/opt/aiotagro/backups"
BRANCH="test"
echo "开始部署 AIOTAGRO 测试环境..."
# 备份当前版本
if [ -d "$PROJECT_DIR" ]; then
echo "备份当前版本..."
timestamp=$(date +%Y%m%d_%H%M%S)
tar -czf "$BACKUP_DIR/frontend_$timestamp.tar.gz" -C "$PROJECT_DIR" .
fi
# 更新代码
cd "$PROJECT_DIR"
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"
# 安装依赖
echo "安装依赖..."
pnpm install
# 构建应用
echo "构建应用..."
pnpm build:antd
# 重启服务
echo "重启服务..."
sudo systemctl restart nginx
echo "部署完成!"
```
## 生产环境部署
### 高可用架构
#### 1. 负载均衡配置
```nginx
# /etc/nginx/nginx.conf
upstream aiogatro_backend {
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 weight=2;
keepalive 32;
}
server {
listen 80;
server_name aiotagro.com www.aiotagro.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name aiotagro.com www.aiotagro.com;
# SSL 配置
ssl_certificate /etc/ssl/certs/aiotagro.crt;
ssl_certificate_key /etc/ssl/private/aiotagro.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
root /var/www/aiotagro/dist;
index index.html;
# 安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# 静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
}
# API 代理
location /api/ {
proxy_pass http://aiogatro_backend;
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;
}
# SPA 路由
location / {
try_files $uri $uri/ /index.html;
}
}
```
### 容器化部署
#### 1. Docker 生产配置
```dockerfile
# Dockerfile.prod
FROM node:18-alpine AS builder
WORKDIR /app
# 复制依赖文件
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建应用
RUN pnpm build:antd
# 生产阶段
FROM nginx:alpine
# 复制构建结果
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]
```
#### 2. Kubernetes 部署
```yaml
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aiotagro-frontend
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: aiotagro-frontend
template:
metadata:
labels:
app: aiotagro-frontend
spec:
containers:
- name: frontend
image: aiotagro/frontend:latest
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: aiotagro-frontend-service
namespace: production
spec:
selector:
app: aiotagro-frontend
ports:
- port: 80
targetPort: 80
type: LoadBalancer
```
### 自动化部署流程
#### 1. CI/CD 配置
```yaml
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [ main ]
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Run tests
run: pnpm test
- name: Build application
run: pnpm build:antd
- name: Build Docker image
run: |
docker build -t $REGISTRY/$IMAGE_NAME:${{ github.sha }} .
- name: Push Docker image
run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login $REGISTRY -u ${{ github.actor }} --password-stdin
docker push $REGISTRY/$IMAGE_NAME:${{ github.sha }}
- name: Deploy to production
run: |
# 部署到生产环境
ssh deploy@production-server << EOF
docker pull $REGISTRY/$IMAGE_NAME:${{ github.sha }}
docker stop aiotagro-frontend || true
docker rm aiotagro-frontend || true
docker run -d --name aiotagro-frontend -p 80:80 $REGISTRY/$IMAGE_NAME:${{ github.sha }}
EOF
```
## 监控和日志
### 1. 应用监控配置
```javascript
// src/utils/monitoring.js
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'
export const initMonitoring = () => {
// 性能监控
getCLS(console.log)
getFID(console.log)
getFCP(console.log)
getLCP(console.log)
getTTFB(console.log)
// 错误监控
window.addEventListener('error', (event) => {
console.error('JavaScript Error:', event.error)
// 发送到监控服务
sendToMonitoringService({
type: 'error',
message: event.error.message,
stack: event.error.stack,
timestamp: new Date().toISOString()
})
})
// 未处理的 Promise 拒绝
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled Promise Rejection:', event.reason)
sendToMonitoringService({
type: 'promise_rejection',
reason: event.reason,
timestamp: new Date().toISOString()
})
})
}
const sendToMonitoringService = (data) => {
// 发送到监控服务
fetch('/api/monitoring', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).catch(console.error)
}
```
### 2. 日志配置
```nginx
# Nginx 日志配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/aiotagro-access.log main;
error_log /var/log/nginx/aiotagro-error.log warn;
```
## 备份和恢复
### 1. 备份策略
```bash
#!/bin/bash
# backup.sh
set -e
BACKUP_DIR="/opt/aiotagro/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="aiotagro_backup_$TIMESTAMP.tar.gz"
echo "开始备份 AIOTAGRO 系统..."
# 备份应用代码
tar -czf "$BACKUP_DIR/$BACKUP_FILE" \
--exclude=node_modules \
--exclude=dist \
--exclude=.git \
/opt/aiotagro/frontend
# 备份 Nginx 配置
tar -czf "$BACKUP_DIR/nginx_config_$TIMESTAMP.tar.gz" /etc/nginx
# 清理旧备份保留最近7天
find "$BACKUP_DIR" -name "aiotagro_backup_*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -name "nginx_config_*.tar.gz" -mtime +7 -delete
echo "备份完成: $BACKUP_DIR/$BACKUP_FILE"
```
### 2. 恢复策略
```bash
#!/bin/bash
# restore.sh
set -e
BACKUP_FILE="$1"
if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup_file>"
exit 1
fi
echo "开始恢复 AIOTAGRO 系统..."
# 停止服务
sudo systemctl stop nginx
# 恢复应用代码
tar -xzf "$BACKUP_FILE" -C /
# 恢复 Nginx 配置(可选)
# tar -xzf "nginx_config_*.tar.gz" -C /
# 启动服务
sudo systemctl start nginx
echo "恢复完成"
```
## 故障排除
### 常见问题
#### 1. 构建失败
**问题**: pnpm build 失败
**解决方案**:
```bash
# 清理缓存
pnpm clean
# 重新安装依赖
pnpm install --force
# 重新构建
pnpm build:antd
```
#### 2. Nginx 配置错误
**问题**: Nginx 启动失败
**解决方案**:
```bash
# 检查配置
sudo nginx -t
# 查看错误日志
sudo tail -f /var/log/nginx/error.log
```
#### 3. 证书问题
**问题**: SSL 证书错误
**解决方案**:
```bash
# 检查证书权限
sudo chmod 600 /etc/ssl/private/aiotagro.key
# 重新加载 Nginx
sudo systemctl reload nginx
```
## 性能优化
### 1. 构建优化
```javascript
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'pinia'],
ui: ['ant-design-vue', '@ant-design/icons-vue'],
utils: ['lodash', 'dayjs', 'axios']
}
}
}
}
})
```
### 2. 缓存策略
```nginx
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
}
# API 缓存
location /api/ {
proxy_cache api_cache;
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
```
## 安全配置
### 1. 安全头设置
```nginx
# 安全头配置
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
```
### 2. 访问控制
```nginx
# IP 限制
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
}
# 速率限制
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
}
```
## 更新和维护
### 1. 定期更新
```bash
#!/bin/bash
# update.sh
set -e
echo "开始更新 AIOTAGRO 系统..."
# 更新代码
cd /opt/aiotagro/frontend
git pull origin main
# 更新依赖
pnpm install
# 构建应用
pnpm build:antd
# 重启服务
sudo systemctl restart nginx
echo "更新完成"
```
### 2. 健康检查
```bash
#!/bin/bash
# health-check.sh
set -e
URL="https://aiotagro.com"
TIMEOUT=10
response=$(curl -s -o /dev/null -w "%{http_code}" --max-time $TIMEOUT $URL)
if [ "$response" -eq 200 ]; then
echo "健康检查通过: $URL"
exit 0
else
echo "健康检查失败: $URL (状态码: $response)"
exit 1
fi
```
通过以上配置和脚本AIOTAGRO 管理系统可以实现稳定、安全、高效的部署和运维。