chore: 添加项目规则文件
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
# 项目规则
|
||||
|
||||
## Git 仓库信息
|
||||
|
||||
| 项目 | 远程地址 | 分支 |
|
||||
|------|---------|------|
|
||||
| 主仓库 (miniapp-api) | `https://git.dxz99wyr.cn/Superuser/miniapp-api.git` | master |
|
||||
| miniapp 子模块 | `https://git.dxz99wyr.cn/Superuser/miniapp-web.git` | master |
|
||||
| backend 子模块 | backend 目录 | - |
|
||||
|
||||
## Git 凭据
|
||||
|
||||
- 用户名: `Superuser`
|
||||
- 密码: `Admin@123`
|
||||
- 凭据已存入 git credential store,无需手动输入
|
||||
|
||||
## Git 推送命令
|
||||
|
||||
推送时需要关闭 SSL 验证(服务器 SSL 证书问题):
|
||||
|
||||
```bash
|
||||
git -c http.sslVerify=false push origin master
|
||||
```
|
||||
+560
@@ -0,0 +1,560 @@
|
||||
# 权益小助手 - CI/CD 流程规范
|
||||
|
||||
## 项目概述
|
||||
|
||||
- **项目名称**: 权益小助手 (QuanYiXiaoZhuShou)
|
||||
- **项目类型**: 微信小程序 + Node.js 后端
|
||||
- **当前版本**: v0.1.0
|
||||
- **Git 仓库**: https://git.dxz99wyr.cn/Superuser/miniapp-api
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
QuanYiXiaoZhuShou/
|
||||
├── backend/ # Node.js 后端服务
|
||||
│ ├── src/ # 源代码
|
||||
│ ├── Dockerfile # Docker 构建文件
|
||||
│ ├── docker-compose.yml # Docker Compose 配置
|
||||
│ ├── nginx-api.conf # Nginx 反向代理配置
|
||||
│ └── package.json # 依赖管理
|
||||
├── miniapp/ # 微信小程序前端
|
||||
│ ├── pages/ # 页面代码
|
||||
│ ├── utils/ # 工具函数
|
||||
│ └── app.js # 小程序入口
|
||||
└── test/ # 测试相关
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
### 后端 (Backend)
|
||||
- **Runtime**: Node.js >= 18.0.0
|
||||
- **Framework**: Express.js 4.18.2
|
||||
- **Database**: MongoDB 7.0
|
||||
- **Process Manager**: PM2
|
||||
- **Container**: Docker + Docker Compose
|
||||
- **Web Server**: Nginx (反向代理)
|
||||
|
||||
### 前端 (Miniapp)
|
||||
- **Platform**: 微信小程序
|
||||
- **Language**: JavaScript
|
||||
- **Build Tool**: 微信开发者工具
|
||||
|
||||
### 服务器环境
|
||||
- **OS**: Ubuntu/Debian (推测)
|
||||
- **Server IP**: 8.136.137.59
|
||||
- **Domain**: api-miniapp.dxz99wyr.cn
|
||||
- **SSL**: 已配置
|
||||
- **Deployment Path**: /var/www/quanyixiaozhushou-app
|
||||
|
||||
## 当前部署状态
|
||||
|
||||
### 服务器部署方式
|
||||
当前使用 **Docker** 容器部署,包含两个容器:
|
||||
|
||||
| 容器名称 | 服务 | 端口 | 状态 |
|
||||
|---------|------|------|------|
|
||||
| `quanyixiaozhushou-app` | Node.js 后端 | 3000 | 运行中 |
|
||||
| `quanyixiaozhushou-mongo` | MongoDB 7.0 | 27018 | 运行中 |
|
||||
|
||||
```bash
|
||||
# 查看容器状态
|
||||
docker ps
|
||||
|
||||
# 查看后端日志
|
||||
docker logs quanyixiaozhushou-app
|
||||
|
||||
# 查看 MongoDB 日志
|
||||
docker logs quanyixiaozhushou-mongo
|
||||
```
|
||||
|
||||
### 环境变量 (生产环境)
|
||||
```env
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
WECHAT_APPID=wxa83262674846ca1a
|
||||
WECHAT_APPSECRET=c40e9d356438f92d10091a115ee50172
|
||||
MONGODB_URI=mongodb://localhost:27017/quanyixiaozhushou
|
||||
JWT_SECRET=your_jwt_secret_key_here_change_in_production
|
||||
JWT_EXPIRES_IN=7d
|
||||
LOG_LEVEL=info
|
||||
```
|
||||
|
||||
## CI/CD 流程设计
|
||||
|
||||
### 1. Git 工作流
|
||||
|
||||
```
|
||||
[Developer] → feature branch → Pull Request → [Code Review] → merge to master → [CI/CD Pipeline] → Deploy
|
||||
```
|
||||
|
||||
### 2. 分支策略
|
||||
|
||||
| 分支 | 用途 | 保护规则 |
|
||||
|------|------|----------|
|
||||
| master | 生产环境分支 | 禁止直接推送,需 PR |
|
||||
| develop | 开发环境分支 | 需 PR |
|
||||
| feature/* | 功能开发 | 自由推送 |
|
||||
| hotfix/* | 紧急修复 | 需 PR 到 master |
|
||||
|
||||
### 3. CI/CD Pipeline 流程
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Git Push/PR] --> B[Checkout Code]
|
||||
B --> C[Install Dependencies]
|
||||
C --> D[Run Tests]
|
||||
D --> E[Lint Check]
|
||||
E --> F[Build Docker Image]
|
||||
F --> G[Push to Registry]
|
||||
G --> H[Deploy to Server]
|
||||
H --> I[Health Check]
|
||||
I --> J[Notify]
|
||||
```
|
||||
|
||||
## 详细 CI/CD 配置
|
||||
|
||||
### Stage 1: 代码检出 (Checkout)
|
||||
|
||||
```yaml
|
||||
# .github/workflows/ci-cd.yml
|
||||
name: CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, develop ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: https://git.dxz99wyr.cn/Superuser/miniapp-api
|
||||
token: ${{ secrets.GIT_ACCESS_TOKEN }}
|
||||
```
|
||||
|
||||
### Stage 2: 依赖安装与测试
|
||||
|
||||
```yaml
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: backend/package-lock.json
|
||||
|
||||
- name: Install backend dependencies
|
||||
working-directory: ./backend
|
||||
run: npm ci
|
||||
|
||||
- name: Run backend tests
|
||||
working-directory: ./backend
|
||||
run: npm test
|
||||
continue-on-error: true # 如果没有测试,不阻塞流程
|
||||
|
||||
- name: Run backend lint
|
||||
working-directory: ./backend
|
||||
run: npm run lint
|
||||
continue-on-error: true
|
||||
```
|
||||
|
||||
### Stage 3: Docker 构建
|
||||
|
||||
```yaml
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io # 或你的私有仓库
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./backend
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ github.repository }}/backend:${{ github.sha }}
|
||||
ghcr.io/${{ github.repository }}/backend:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
```
|
||||
|
||||
### Stage 4: 部署到服务器
|
||||
|
||||
```yaml
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: 8.136.137.59
|
||||
username: root
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
script: |
|
||||
# 拉取最新镜像
|
||||
docker pull ghcr.io/${{ github.repository }}/backend:latest
|
||||
|
||||
# 停止旧容器
|
||||
docker stop quanyi-backend || true
|
||||
docker rm quanyi-backend || true
|
||||
|
||||
# 启动新容器
|
||||
docker run -d \
|
||||
--name quanyi-backend \
|
||||
--restart unless-stopped \
|
||||
-p 3000:3000 \
|
||||
-e PORT=3000 \
|
||||
-e NODE_ENV=production \
|
||||
-e WECHAT_APPID=${{ secrets.WECHAT_APPID }} \
|
||||
-e WECHAT_APPSECRET=${{ secrets.WECHAT_APPSECRET }} \
|
||||
-e MONGODB_URI=${{ secrets.MONGODB_URI }} \
|
||||
-e JWT_SECRET=${{ secrets.JWT_SECRET }} \
|
||||
-v /var/www/quanyixiaozhushou-app/public/uploads:/app/public/uploads \
|
||||
ghcr.io/${{ github.repository }}/backend:latest
|
||||
|
||||
# 健康检查
|
||||
sleep 10
|
||||
curl -f http://localhost:3000/health || exit 1
|
||||
```
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
### GitHub Secrets 需要配置
|
||||
|
||||
| Secret Name | Description | Example |
|
||||
|-------------|-------------|---------|
|
||||
| `GIT_ACCESS_TOKEN` | Git 仓库访问令牌 | 用于拉取 `https://git.dxz99wyr.cn/Superuser/miniapp-api` |
|
||||
| `SSH_PRIVATE_KEY` | 服务器 SSH 私钥 | `-----BEGIN OPENSSH PRIVATE KEY-----...` |
|
||||
| `WECHAT_APPID` | 微信小程序 AppID | `wxa83262674846ca1a` |
|
||||
| `WECHAT_APPSECRET` | 微信小程序 AppSecret | `c40e9d356438f92d10091a115ee50172` |
|
||||
| `MONGODB_URI` | MongoDB 连接字符串 | `mongodb://localhost:27017/quanyixiaozhushou` |
|
||||
| `JWT_SECRET` | JWT 密钥 | `your_jwt_secret_key` |
|
||||
|
||||
## 部署脚本 (服务器端)
|
||||
|
||||
### 1. 初始化脚本 (首次部署)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-init.sh
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="/var/www/quanyixiaozhushou-app"
|
||||
BACKUP_DIR="/var/backups/quanyixiaozhushou"
|
||||
|
||||
# 创建目录
|
||||
mkdir -p $PROJECT_DIR
|
||||
mkdir -p $BACKUP_DIR
|
||||
mkdir -p $PROJECT_DIR/public/uploads
|
||||
mkdir -p $PROJECT_DIR/public/avatars
|
||||
|
||||
# 安装 Docker (如果未安装)
|
||||
if ! command -v docker &> /dev/null; then
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
fi
|
||||
|
||||
# 安装 Docker Compose
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
fi
|
||||
|
||||
echo "初始化完成"
|
||||
```
|
||||
|
||||
### 2. 部署脚本 (日常更新)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy.sh
|
||||
|
||||
set -e
|
||||
|
||||
IMAGE_TAG=${1:-latest}
|
||||
PROJECT_DIR="/var/www/quanyixiaozhushou-app"
|
||||
BACKUP_DIR="/var/backups/quanyixiaozhushou"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
echo "=== 开始部署 ==="
|
||||
echo "镜像标签: $IMAGE_TAG"
|
||||
|
||||
# 1. 备份当前数据
|
||||
echo "[1/5] 备份当前数据..."
|
||||
mkdir -p $BACKUP_DIR/$TIMESTAMP
|
||||
cp -r $PROJECT_DIR/public/uploads $BACKUP_DIR/$TIMESTAMP/ 2>/dev/null || true
|
||||
mongodump --db quanyixiaozhushou --out $BACKUP_DIR/$TIMESTAMP/ 2>/dev/null || true
|
||||
|
||||
# 2. 拉取最新镜像
|
||||
echo "[2/5] 拉取最新镜像..."
|
||||
docker pull ghcr.io/your-repo/quanyixiaozhushou-backend:$IMAGE_TAG
|
||||
|
||||
# 3. 停止旧容器
|
||||
echo "[3/5] 停止旧容器..."
|
||||
docker stop quanyi-backend 2>/dev/null || true
|
||||
docker rm quanyi-backend 2>/dev/null || true
|
||||
|
||||
# 4. 启动新容器
|
||||
echo "[4/5] 启动新容器..."
|
||||
docker run -d \
|
||||
--name quanyi-backend \
|
||||
--restart unless-stopped \
|
||||
-p 3000:3000 \
|
||||
-e PORT=3000 \
|
||||
-e NODE_ENV=production \
|
||||
-e WECHAT_APPID=$WECHAT_APPID \
|
||||
-e WECHAT_APPSECRET=$WECHAT_APPSECRET \
|
||||
-e MONGODB_URI=$MONGODB_URI \
|
||||
-e JWT_SECRET=$JWT_SECRET \
|
||||
-v $PROJECT_DIR/public/uploads:/app/public/uploads \
|
||||
-v $PROJECT_DIR/public/avatars:/app/public/avatars \
|
||||
ghcr.io/your-repo/quanyixiaozhushou-backend:$IMAGE_TAG
|
||||
|
||||
# 5. 健康检查
|
||||
echo "[5/5] 健康检查..."
|
||||
sleep 5
|
||||
|
||||
MAX_RETRIES=10
|
||||
RETRY_COUNT=0
|
||||
|
||||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||
if curl -f -s http://localhost:3000/health > /dev/null; then
|
||||
echo "✅ 服务健康检查通过"
|
||||
break
|
||||
fi
|
||||
|
||||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||
echo "等待服务启动... ($RETRY_COUNT/$MAX_RETRIES)"
|
||||
sleep 3
|
||||
done
|
||||
|
||||
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
|
||||
echo "❌ 健康检查失败,执行回滚..."
|
||||
# 回滚逻辑
|
||||
docker stop quanyi-backend
|
||||
docker rm quanyi-backend
|
||||
# 启动上一个版本
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 清理旧镜像
|
||||
docker image prune -f
|
||||
|
||||
echo "=== 部署完成 ==="
|
||||
echo "备份位置: $BACKUP_DIR/$TIMESTAMP"
|
||||
```
|
||||
|
||||
## 健康检查端点
|
||||
|
||||
确保后端有以下健康检查端点:
|
||||
|
||||
```javascript
|
||||
// src/app.js
|
||||
app.get('/health', (req, res) => {
|
||||
res.status(200).json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
version: process.env.npm_package_version || '1.0.0'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 微信小程序 CI/CD
|
||||
|
||||
### 自动上传脚本
|
||||
|
||||
```yaml
|
||||
# .github/workflows/miniapp-deploy.yml
|
||||
name: Miniapp Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- 'miniapp/**'
|
||||
|
||||
jobs:
|
||||
deploy-miniapp:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Install miniprogram-ci
|
||||
run: npm install -g miniprogram-ci
|
||||
|
||||
- name: Upload to WeChat
|
||||
working-directory: ./miniapp
|
||||
run: |
|
||||
miniprogram-ci upload \
|
||||
--pp ./ \
|
||||
--pkp ${{ secrets.WECHAT_PRIVATE_KEY }} \
|
||||
--appid ${{ secrets.WECHAT_APPID }} \
|
||||
--uv ${{ github.run_number }} \
|
||||
--enable-es6 true
|
||||
```
|
||||
|
||||
## 监控与告警
|
||||
|
||||
### 1. 日志监控
|
||||
|
||||
```bash
|
||||
# 查看实时日志
|
||||
docker logs -f quanyi-backend
|
||||
|
||||
# 查看错误日志
|
||||
docker logs quanyi-backend 2>&1 | grep ERROR
|
||||
```
|
||||
|
||||
### 进程监控
|
||||
|
||||
```bash
|
||||
# Docker 容器监控
|
||||
docker stats quanyixiaozhushou-app
|
||||
|
||||
# 进入容器调试
|
||||
docker exec -it quanyixiaozhushou-app sh
|
||||
```
|
||||
|
||||
### 3. 告警规则
|
||||
|
||||
- 服务 5xx 错误率 > 1%
|
||||
- 响应时间 > 2s
|
||||
- 内存使用 > 80%
|
||||
- CPU 使用 > 80%
|
||||
- 磁盘使用 > 85%
|
||||
|
||||
## 回滚策略
|
||||
|
||||
### 自动回滚条件
|
||||
|
||||
- 健康检查失败
|
||||
- 错误率突增
|
||||
- 部署后 5 分钟内服务不可用
|
||||
|
||||
### 回滚脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# rollback.sh
|
||||
|
||||
PREVIOUS_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep quanyixiaozhushou-backend | head -2 | tail -1)
|
||||
|
||||
echo "回滚到上一个版本: $PREVIOUS_IMAGE"
|
||||
|
||||
docker stop quanyi-backend
|
||||
docker rm quanyi-backend
|
||||
docker run -d \
|
||||
--name quanyi-backend \
|
||||
--restart unless-stopped \
|
||||
-p 3000:3000 \
|
||||
-e PORT=3000 \
|
||||
-e NODE_ENV=production \
|
||||
-v /var/www/quanyixiaozhushou-app/public/uploads:/app/public/uploads \
|
||||
$PREVIOUS_IMAGE
|
||||
|
||||
echo "回滚完成"
|
||||
```
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
### MongoDB 迁移脚本
|
||||
|
||||
```javascript
|
||||
// migrations/001_add_subscription_type.js
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
async function migrate() {
|
||||
await mongoose.connect(process.env.MONGODB_URI);
|
||||
|
||||
// 添加 type 字段到现有订阅记录
|
||||
await mongoose.connection.collection('usersubscriptions').updateMany(
|
||||
{ type: { $exists: false } },
|
||||
{ $set: { type: 'version-update' } }
|
||||
);
|
||||
|
||||
console.log('Migration completed');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
migrate().catch(console.error);
|
||||
```
|
||||
|
||||
## 安全检查清单
|
||||
|
||||
- [ ] 环境变量不提交到 Git
|
||||
- [ ] 使用 secrets 管理敏感信息
|
||||
- [ ] Docker 镜像使用非 root 用户运行
|
||||
- [ ] 启用 HTTPS
|
||||
- [ ] 配置防火墙规则
|
||||
- [ ] 定期更新依赖
|
||||
- [ ] 启用日志审计
|
||||
- [ ] 配置备份策略
|
||||
|
||||
## 附录
|
||||
|
||||
### A. 常用命令
|
||||
|
||||
```bash
|
||||
# 查看容器状态
|
||||
docker ps
|
||||
|
||||
# 查看容器日志
|
||||
docker logs quanyi-backend
|
||||
|
||||
# 进入容器
|
||||
docker exec -it quanyi-backend sh
|
||||
|
||||
# 重启容器
|
||||
docker restart quanyi-backend
|
||||
|
||||
# 查看资源使用
|
||||
docker stats quanyi-backend
|
||||
```
|
||||
|
||||
### B. 故障排查
|
||||
|
||||
```bash
|
||||
# 服务无法启动
|
||||
docker logs quanyi-backend
|
||||
|
||||
# MongoDB 连接失败
|
||||
docker exec -it quanyi-backend node -e "require('mongoose').connect(process.env.MONGODB_URI).then(() => console.log('OK')).catch(e => console.error(e))"
|
||||
|
||||
# 端口占用
|
||||
netstat -tlnp | grep 3000
|
||||
```
|
||||
|
||||
### C. 联系方式与仓库信息
|
||||
|
||||
- **Git 仓库**: https://git.dxz99wyr.cn/Superuser/miniapp-api
|
||||
- **服务器**: 8.136.137.59
|
||||
- **域名**: api-miniapp.dxz99wyr.cn
|
||||
- **SSH 密钥**: D:\003_Project\小程序连接.pem
|
||||
|
||||
### D. Git 仓库配置命令
|
||||
|
||||
```bash
|
||||
# 添加远程仓库
|
||||
git remote add origin https://git.dxz99wyr.cn/Superuser/miniapp-api
|
||||
|
||||
# 推送代码
|
||||
git push -u origin master
|
||||
|
||||
# 拉取最新代码
|
||||
git pull origin master
|
||||
```
|
||||
+1
-1
Submodule backend updated: 8bab5d67b2...0ff5a02155
Reference in New Issue
Block a user