768 lines
14 KiB
Markdown
768 lines
14 KiB
Markdown
|
|
# 部署文档
|
|||
|
|
|
|||
|
|
## 部署概述
|
|||
|
|
|
|||
|
|
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 管理系统可以实现稳定、安全、高效的部署和运维。
|