docs: 重组文档结构,按模块分类
新的文档结构:
docs/
├── README.md # 文档中心导航
├── modules/ # 模块文档
│ ├── auth/ # 认证模块
│ │ ├── README.md
│ │ ├── feishu-login.md
│ │ ├── feishu-qrcode.md
│ │ └── feishu-notification.md
│ ├── approval/ # 审批流程模块
│ │ └── README.md
│ ├── business-trip/ # 出差申请模块
│ │ └── README.md
│ └── user/ # 用户管理模块
│ └── README.md
└── guides/ # 指南文档
├── deployment.md
├── environment.md
├── git-workflow.md
└── ...
每个模块都有独立的 README.md 说明概述、API、关键文件等
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
# X-Server Mobile 部署检查清单
|
||||
|
||||
## 部署前检查
|
||||
|
||||
### 服务器环境
|
||||
- [ ] 服务器已安装 1Panel 面板
|
||||
- [ ] 已安装 OpenResty 并正常运行
|
||||
- [ ] 已安装 MySQL 容器(1Panel 管理)
|
||||
- [ ] 已安装 Redis 容器(1Panel 管理)
|
||||
- [ ] Docker 网络配置正确(1panel-network 存在)
|
||||
|
||||
### 网络配置
|
||||
- [ ] 域名 DNS 已解析到服务器 IP
|
||||
- [ ] 服务器防火墙已开放 80、443 端口
|
||||
- [ ] 服务器可从外网访问
|
||||
|
||||
### 数据库准备
|
||||
- [ ] 创建生产数据库 `xserver`
|
||||
- [ ] 创建专用数据库用户 `xserver`
|
||||
- [ ] 授予用户权限
|
||||
- [ ] 导入数据库结构和初始数据
|
||||
|
||||
### SSL 证书
|
||||
- [ ] 安装 certbot: `apt-get install certbot`
|
||||
- [ ] 获取证书: `certbot certonly --standalone -d xsm.hnxinyouhe.com`
|
||||
- [ ] 验证证书路径正确
|
||||
|
||||
### 环境变量
|
||||
- [ ] 复制 `.env.production.template` 为 `.env.production`
|
||||
- [ ] 填写数据库配置
|
||||
- [ ] 填写 Redis 配置
|
||||
- [ ] 填写飞书配置
|
||||
- [ ] 更新飞书回调地址为 `https://xsm.hnxinyouhe.com/login/callback`
|
||||
|
||||
### 目录结构
|
||||
- [ ] 创建部署目录: `/opt/x-server-mobile`
|
||||
- [ ] 创建子目录: frontend, backend, logs, backup
|
||||
- [ ] 设置正确的目录权限
|
||||
|
||||
---
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 1. 准备服务器环境
|
||||
|
||||
```bash
|
||||
# SSH 登录服务器
|
||||
ssh root@your-server
|
||||
|
||||
# 创建目录结构
|
||||
mkdir -p /opt/x-server-mobile/{frontend,backend,logs,backup}
|
||||
mkdir -p /opt/x-server-mobile/logs/backend
|
||||
mkdir -p /opt/x-server-mobile/logs/nginx
|
||||
|
||||
# 创建日志文件
|
||||
touch /opt/x-server-mobile/logs/nginx_access.log
|
||||
touch /opt/x-server-mobile/logs/nginx_error.log
|
||||
```
|
||||
|
||||
### 2. 配置 OpenResty
|
||||
|
||||
```bash
|
||||
# 复制配置文件到 OpenResty 配置目录
|
||||
cp deploy/nginx/x-server-mobile-prod.conf /usr/local/openresty/nginx/conf/conf.d/x-server-mobile.conf
|
||||
|
||||
# 测试配置
|
||||
openresty -t
|
||||
|
||||
# 如果测试通过,重载配置
|
||||
openresty -s reload
|
||||
```
|
||||
|
||||
### 3. 构建前端
|
||||
|
||||
```bash
|
||||
# 在开发环境
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# 验证构建产物
|
||||
ls -la dist/
|
||||
```
|
||||
|
||||
### 4. 部署
|
||||
|
||||
```bash
|
||||
# 方式1: 使用部署脚本
|
||||
./deploy.sh your-server-ip
|
||||
|
||||
# 方式2: 手动部署
|
||||
# 上传前端
|
||||
scp -r frontend/dist/* root@server:/opt/x-server-mobile/frontend/
|
||||
|
||||
# 上传后端
|
||||
scp -r backend/ root@server:/opt/x-server-mobile/backend/
|
||||
|
||||
# 上传 docker-compose
|
||||
scp docker-compose.prod.yml root@server:/opt/x-server-mobile/
|
||||
```
|
||||
|
||||
### 5. 启动后端
|
||||
|
||||
```bash
|
||||
# SSH 登录服务器
|
||||
ssh root@server
|
||||
|
||||
# 进入部署目录
|
||||
cd /opt/x-server-mobile
|
||||
|
||||
# 加载环境变量
|
||||
source .env.production
|
||||
|
||||
# 启动容器
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# 查看容器状态
|
||||
docker ps | grep x-server
|
||||
|
||||
# 查看日志
|
||||
docker logs -f x-server-backend-prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署后验证
|
||||
|
||||
### 前端验证
|
||||
- [ ] 访问 `https://xsm.hnxinyouhe.com` 显示登录页面
|
||||
- [ ] 页面样式加载正常
|
||||
- [ ] 浏览器控制台无错误
|
||||
|
||||
### 后端验证
|
||||
- [ ] 容器运行正常: `docker ps | grep x-server`
|
||||
- [ ] 健康检查通过
|
||||
- [ ] 日志无错误信息
|
||||
|
||||
### 功能验证
|
||||
- [ ] 邮箱密码登录功能正常
|
||||
- [ ] 飞书客户端内免登正常
|
||||
- [ ] 飞书扫码登录正常
|
||||
- [ ] 审批列表正常显示
|
||||
- [ ] 出差申请功能正常
|
||||
- [ ] 飞书卡片通知正常
|
||||
|
||||
### 飞书回调验证
|
||||
- [ ] 飞书后台配置回调地址: `https://xsm.hnxinyouhe.com/login/callback`
|
||||
- [ ] 点击飞书卡片"查看详情"跳转正确
|
||||
- [ ] 快速审批按钮功能正常
|
||||
|
||||
---
|
||||
|
||||
## 监控配置
|
||||
|
||||
### 日志监控
|
||||
|
||||
```bash
|
||||
# Nginx 访问日志
|
||||
tail -f /opt/x-server-mobile/logs/nginx_access.log
|
||||
|
||||
# Nginx 错误日志
|
||||
tail -f /opt/x-server-mobile/logs/nginx_error.log
|
||||
|
||||
# 后端容器日志
|
||||
docker logs -f x-server-backend-prod
|
||||
|
||||
# 后端应用日志
|
||||
tail -f /opt/x-server-mobile/logs/backend/*.log
|
||||
```
|
||||
|
||||
### 性能监控
|
||||
|
||||
```bash
|
||||
# 容器资源使用
|
||||
docker stats x-server-backend-prod
|
||||
|
||||
# 磁盘使用
|
||||
du -sh /opt/x-server-mobile/*
|
||||
|
||||
# 内存使用
|
||||
free -h
|
||||
```
|
||||
|
||||
### 数据库监控
|
||||
|
||||
```bash
|
||||
# 检查 MySQL 连接
|
||||
docker exec x-server-backend-prod php -r "
|
||||
try {
|
||||
new PDO('mysql:host=DB_HOST;dbname=xserver', 'xserver', 'password');
|
||||
echo 'Database connection OK\n';
|
||||
} catch (Exception \$e) {
|
||||
echo 'Database connection FAILED: ' . \$e->getMessage() . '\n';
|
||||
}
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 回滚准备
|
||||
|
||||
### 备份检查
|
||||
|
||||
```bash
|
||||
# 检查备份目录
|
||||
ls -la /opt/x-server-mobile/backup/
|
||||
|
||||
# 查看最新备份
|
||||
ls -lt /opt/x-server-mobile/backup/ | head -5
|
||||
```
|
||||
|
||||
### 回滚测试
|
||||
|
||||
```bash
|
||||
# 测试回滚脚本
|
||||
./rollback.sh <backup_name>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 定期维护
|
||||
|
||||
### 每周
|
||||
- [ ] 检查容器运行状态
|
||||
- [ ] 检查日志错误
|
||||
- [ ] 检查磁盘空间
|
||||
|
||||
### 每月
|
||||
- [ ] 更新 SSL 证书(自动续期)
|
||||
- [ ] 数据库备份
|
||||
- [ ] 日志归档和清理
|
||||
|
||||
### 每季度
|
||||
- [ ] 安全更新检查
|
||||
- [ ] 性能优化评估
|
||||
- [ ] 灾难恢复演练
|
||||
|
||||
---
|
||||
|
||||
## 应急处理
|
||||
|
||||
### 服务异常
|
||||
|
||||
```bash
|
||||
# 查看容器状态
|
||||
docker ps -a | grep x-server
|
||||
|
||||
# 重启后端容器
|
||||
docker restart x-server-backend-prod
|
||||
|
||||
# 查看详细日志
|
||||
docker logs --tail 100 x-server-backend-prod
|
||||
```
|
||||
|
||||
### 数据库异常
|
||||
|
||||
```bash
|
||||
# 检查 MySQL 容器
|
||||
docker ps | grep mysql
|
||||
|
||||
# 进入 MySQL
|
||||
docker exec -it <mysql-container> mysql -uxserver -p
|
||||
|
||||
# 检查连接数
|
||||
SHOW PROCESSLIST;
|
||||
```
|
||||
|
||||
### 网络异常
|
||||
|
||||
```bash
|
||||
# 检查端口监听
|
||||
netstat -tlnp | grep -E '80|443|8787'
|
||||
|
||||
# 检查防火墙
|
||||
ufw status
|
||||
|
||||
# 测试外网访问
|
||||
curl -I https://xsm.hnxinyouhe.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 联系信息
|
||||
|
||||
- 开发负责人: ___________
|
||||
- 运维负责人: ___________
|
||||
- 紧急联系电话: ___________
|
||||
@@ -0,0 +1,254 @@
|
||||
# uniservice-mobile.hnxinyouhe.com 线上部署说明
|
||||
|
||||
## 线上环境信息
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| **域名** | uniservice-mobile.hnxinyouhe.com |
|
||||
| **站点目录** | /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index |
|
||||
| **项目目录** | /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server |
|
||||
| **后端容器** | x-server-backend-prod (端口 8787) |
|
||||
| **MySQL 容器** | 1Panel-mysql-XyxS |
|
||||
| **Redis 容器** | 1Panel-redis-pxdb |
|
||||
| **Docker 网络** | 1panel-network |
|
||||
|
||||
---
|
||||
|
||||
## 部署架构
|
||||
|
||||
| 组件 | 部署方式 |
|
||||
|------|---------|
|
||||
| **前端** | 本地构建 → 上传静态文件 |
|
||||
| **后端** | Git 拉取 → Docker 重启 |
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
/opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/
|
||||
├── index.html # 前端入口
|
||||
├── assets/ # 前端静态资源
|
||||
└── server/ # 整个项目(Git 仓库)
|
||||
├── backend/ # 后端代码
|
||||
│ ├── app/
|
||||
│ ├── config/
|
||||
│ └── ...
|
||||
├── deploy/ # 部署配置
|
||||
│ ├── docker-compose.prod.yml
|
||||
│ ├── .env.production
|
||||
│ └── deploy.sh
|
||||
├── frontend/ # 前端源码(不使用)
|
||||
├── docs/ # 文档
|
||||
└── logs/ # 日志
|
||||
└── backend/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 快速部署
|
||||
|
||||
### 前端部署(本地)
|
||||
|
||||
```bash
|
||||
# 本地构建
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm run build
|
||||
|
||||
# 上传静态文件
|
||||
rsync -avz --delete \
|
||||
frontend/dist/ \
|
||||
root@45.153.130.80:/opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/
|
||||
```
|
||||
|
||||
### 后端部署(服务器)
|
||||
|
||||
```bash
|
||||
# 登录服务器
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server
|
||||
|
||||
# 拉取代码
|
||||
git pull origin master
|
||||
|
||||
# 重启容器
|
||||
docker-compose -f deploy/docker-compose.prod.yml down
|
||||
docker-compose -f deploy/docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
或使用部署脚本:
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server
|
||||
./deploy/deploy.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 首次部署
|
||||
|
||||
### 1. 克隆后端代码
|
||||
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index
|
||||
|
||||
# 克隆 master 分支
|
||||
git clone <your-git-repository-url> server
|
||||
cd server
|
||||
git checkout master
|
||||
```
|
||||
|
||||
### 2. 上传 Dockerfile
|
||||
|
||||
```bash
|
||||
# 本地执行
|
||||
scp backend/Dockerfile.prod root@45.153.130.80:/opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server/backend/
|
||||
```
|
||||
|
||||
### 3. 配置环境变量
|
||||
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
vi /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server/deploy/.env.production
|
||||
```
|
||||
|
||||
填写飞书配置:
|
||||
|
||||
```env
|
||||
FEISHU_APP_ID=cli_axxxxxxxxxxxx
|
||||
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
### 4. 创建日志目录
|
||||
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
mkdir -p /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server/logs/backend
|
||||
```
|
||||
|
||||
### 5. 上传部署脚本
|
||||
|
||||
```bash
|
||||
# 本地执行
|
||||
scp deploy/server-deploy.sh root@45.153.130.80:/opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server/deploy/deploy.sh
|
||||
|
||||
# 赋予执行权限
|
||||
ssh root@45.153.130.80
|
||||
chmod +x /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server/deploy/deploy.sh
|
||||
```
|
||||
|
||||
### 6. 启动后端容器
|
||||
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/server
|
||||
docker-compose -f deploy/docker-compose.prod.yml up -d
|
||||
docker ps | grep x-server
|
||||
```
|
||||
|
||||
### 7. 上传前端
|
||||
|
||||
```bash
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm run build
|
||||
rsync -avz --delete \
|
||||
frontend/dist/ \
|
||||
root@45.153.130.80:/opt/1panel/www/sites/uniservice-mobile.hnxinyouhe.com/index/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1Panel Nginx 配置
|
||||
|
||||
在 1Panel 面板(网站设置 → 配置文件)添加反向代理:
|
||||
|
||||
```nginx
|
||||
# 后端 API
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
# 飞书登录回调
|
||||
location /login {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
location /login/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
location /login/qrcode {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
|
||||
# 飞书卡片回调
|
||||
location /feishu/card/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署验证
|
||||
|
||||
```bash
|
||||
# 检查前端
|
||||
curl -I https://uniservice-mobile.hnxinyouhe.com
|
||||
|
||||
# 检查后端容器
|
||||
ssh root@45.153.130.80
|
||||
docker ps | grep x-server
|
||||
docker logs -f x-server-backend-prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 问题 | 解决方案 |
|
||||
|------|---------|
|
||||
| API 404 | 检查 Nginx 反向代理配置 |
|
||||
| 容器启动失败 | 检查数据库/Redis 容器状态,查看日志 |
|
||||
| 飞书登录失败 | 检查 `/login/*` 反向代理配置 |
|
||||
| 静态资源 404 | 确认前端上传到正确目录 |
|
||||
|
||||
---
|
||||
|
||||
## 文件清单
|
||||
|
||||
需要上传到服务器的文件:
|
||||
|
||||
| 文件 | 目标位置 |
|
||||
|------|---------|
|
||||
| `backend/Dockerfile.prod` | `server/backend/` |
|
||||
| `deploy/docker-compose.prod.yml` | `server/deploy/` |
|
||||
| `deploy/.env.production` | `server/deploy/` |
|
||||
| `deploy/server-deploy.sh` | `server/deploy/deploy.sh` |
|
||||
@@ -0,0 +1,219 @@
|
||||
# 开发环境反向代理配置指南
|
||||
|
||||
本指南用于配置开发环境的 OpenResty 和 frpc,以便将本地 API 暴露到公网调试飞书登录。
|
||||
|
||||
## 前提条件
|
||||
|
||||
- 已安装并运行 OpenResty
|
||||
- 已安装并运行 frpc
|
||||
- Docker 中运行的后端服务 (localhost:8787)
|
||||
|
||||
## 配置步骤
|
||||
|
||||
### 1. OpenResty 配置
|
||||
|
||||
在你的 OpenResty 配置目录中创建以下配置文件:
|
||||
|
||||
```nginx
|
||||
# /usr/local/openresty/nginx/conf/conf.d/x-server-api.conf
|
||||
|
||||
server {
|
||||
listen 8080; # 本地开发端口,避免与 80 端口冲突
|
||||
server_name api.x-server.local;
|
||||
|
||||
# API 反向代理
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8787/api/;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
|
||||
# CORS 配置(飞书请求需要)
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Tenant-Key';
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
return 200 "OK\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
重载配置:
|
||||
```bash
|
||||
sudo openresty -s reload
|
||||
# 或
|
||||
sudo systemctl reload openresty
|
||||
```
|
||||
|
||||
### 2. frpc 配置
|
||||
|
||||
配置 frpc 将本地 OpenResty 服务暴露到公网:
|
||||
|
||||
```ini
|
||||
# ~/.frpc.ini 或 /etc/frp/frpc.ini
|
||||
|
||||
[common]
|
||||
server_addr = your-frp-server.com # 你的 frp 服务器地址
|
||||
server_port = 7000
|
||||
token = your-token
|
||||
|
||||
[x-server-api]
|
||||
type = http
|
||||
local_ip = 127.0.0.1
|
||||
local_port = 8080 # OpenResty 监听端口
|
||||
custom_domains = api-dev.x-server.your-domain.com # 开发环境域名
|
||||
|
||||
# 可选:启用加密和压缩
|
||||
use_encryption = true
|
||||
use_compression = true
|
||||
```
|
||||
|
||||
启动 frpc:
|
||||
```bash
|
||||
frpc -c ~/.frpc.ini
|
||||
```
|
||||
|
||||
### 3. 本地 hosts 配置
|
||||
|
||||
在本地开发时配置 hosts:
|
||||
|
||||
```bash
|
||||
# /etc/hosts
|
||||
127.0.0.1 api.x-server.local
|
||||
```
|
||||
|
||||
### 4. 飞书应用配置
|
||||
|
||||
在飞书开放平台配置开发环境回调 URL:
|
||||
|
||||
```
|
||||
https://api-dev.x-server.your-domain.com/api/v1/auth/feishu-login
|
||||
```
|
||||
|
||||
## 验证配置
|
||||
|
||||
### 1. 本地测试
|
||||
```bash
|
||||
# 直接访问后端
|
||||
curl http://localhost:8787/api/v1/user/info
|
||||
|
||||
# 通过 OpenResty 访问
|
||||
curl http://localhost:8080/api/v1/user/info
|
||||
|
||||
# 通过本地域名访问
|
||||
curl http://api.x-server.local/api/v1/user/info
|
||||
```
|
||||
|
||||
### 2. 公网测试
|
||||
```bash
|
||||
# 通过 frps 域名访问
|
||||
curl https://api-dev.x-server.your-domain.com/api/v1/user/info
|
||||
```
|
||||
|
||||
### 3. 飞书调试
|
||||
1. 在飞书开放平台创建测试应用
|
||||
2. 配置回调 URL 为开发环境域名
|
||||
3. 使用飞书 APP ID 和 APP SECRET 进行测试
|
||||
4. 检查后端日志查看请求详情
|
||||
|
||||
## 开发与生产环境区分
|
||||
|
||||
### 开发环境(使用 frpc)
|
||||
- 域名:`api-dev.x-server.your-domain.com`
|
||||
- 使用 frpc 暴露本地服务
|
||||
- CORS 允许所有来源
|
||||
- 详细日志输出
|
||||
|
||||
### 生产环境(不使用 frpc)
|
||||
- 域名:`api.x-server.com`
|
||||
- 直接部署到服务器
|
||||
- CORS 严格限制
|
||||
- 日志级别调整
|
||||
|
||||
## 故障排查
|
||||
|
||||
### OpenResty 无法访问后端
|
||||
1. 检查 Docker 容器是否运行:`docker ps`
|
||||
2. 检查端口是否正确:`docker ps | grep 8787`
|
||||
3. 检查网络连通性:`curl http://127.0.0.1:8787`
|
||||
|
||||
### frpc 连接失败
|
||||
1. 检查 frp 服务器是否可访问
|
||||
2. 检查 token 是否正确
|
||||
3. 查看 frpc 日志:`frpc -c ~/.frpc.ini`
|
||||
|
||||
### 飞书回调失败
|
||||
1. 检查域名 DNS 解析是否指向 frp 服务器
|
||||
2. 检查 frp 服务器是否配置了域名白名单
|
||||
3. 检查后端日志是否收到请求
|
||||
4. 验证 CORS 配置是否正确
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **开发环境使用独立的域名和 token**
|
||||
2. **定期更新 frp token**
|
||||
3. **不要在代码中硬编码生产环境配置**
|
||||
4. **使用环境变量管理敏感信息**
|
||||
5. **生产环境部署前移除 frpc 配置**
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
# 查看 Docker 容器日志
|
||||
docker logs x-server-backend -f
|
||||
|
||||
# 重启后端服务
|
||||
docker compose restart backend
|
||||
|
||||
# 重载 OpenResty 配置
|
||||
sudo openresty -s reload
|
||||
|
||||
# 查看 frpc 状态
|
||||
frpc status -c ~/.frpc.ini
|
||||
|
||||
# 测试 API 连通性
|
||||
curl -v http://localhost:8787/api/v1/user/info
|
||||
```
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
创建 `.env.development` 文件用于开发环境:
|
||||
|
||||
```env
|
||||
# 后端配置
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=x_server_mobile
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=mysql_xEsdPa
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
|
||||
# 飞书配置(开发环境)
|
||||
FEISHU_APP_ID=cli_xxxxxxxxxxxxx
|
||||
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
|
||||
FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# API 配置
|
||||
API_BASE_URL=http://localhost:8787
|
||||
PUBLIC_API_URL=https://api-dev.x-server.your-domain.com
|
||||
```
|
||||
|
||||
生产环境使用 `.env.production` 文件,移除 frpc 相关配置。
|
||||
@@ -0,0 +1,257 @@
|
||||
# 环境配置说明
|
||||
|
||||
本文档说明开发环境和生产环境的区别,避免混淆。
|
||||
|
||||
---
|
||||
|
||||
## 一、环境对比
|
||||
|
||||
| 项目 | 开发环境 | 生产环境 |
|
||||
|------|----------|----------|
|
||||
| **Git 分支** | `feature/mzl-dev` | `master` |
|
||||
| **服务器** | 本地 WSL2 | 45.153.130.80 |
|
||||
| **域名** | `xsm.dev.hnxinyouhe.com` | `uniservice-mobile.hnxinyouhe.com` |
|
||||
| **前端端口** | 5173 (Vite Dev) | 静态文件托管 |
|
||||
| **后端端口** | 8787 (Webman) | 8787 (Webman) |
|
||||
| **代理** | OpenResty 8080 + frpc 内网穿透 | OpenResty 80/443 |
|
||||
| **数据库** | `1Panel-mysql-409s` | 生产 MySQL 容器 |
|
||||
| **调试模式** | `APP_DEBUG=true` | `APP_DEBUG=false` |
|
||||
| **日志级别** | debug | info |
|
||||
|
||||
---
|
||||
|
||||
## 二、域名使用说明
|
||||
|
||||
### 开发环境域名
|
||||
```
|
||||
xsm.dev.hnxinyouhe.com
|
||||
```
|
||||
- 用途:飞书登录回调调试
|
||||
- 通过 frpc 内网穿透暴露到公网
|
||||
- 只在开发时使用
|
||||
|
||||
### 生产环境域名
|
||||
```
|
||||
uniservice-mobile.hnxinyouhe.com
|
||||
```
|
||||
- 用途:正式生产环境
|
||||
- 用户实际访问的域名
|
||||
- 飞书开放平台配置的回调地址
|
||||
|
||||
---
|
||||
|
||||
## 三、飞书开放平台配置
|
||||
|
||||
### 生产环境配置(重要!)
|
||||
飞书开放平台必须配置生产环境的回调地址:
|
||||
|
||||
| 配置项 | 值 |
|
||||
|--------|-----|
|
||||
| **重定向 URL** | `https://uniservice-mobile.hnxinyouhe.com/login/callback` |
|
||||
| **可信域名** | `uniservice-mobile.hnxinyouhe.com` |
|
||||
|
||||
**注意**:开发环境使用 frpc 穿透,但飞书回调仍需要配置正式域名。开发时可以临时添加开发域名到白名单进行测试。
|
||||
|
||||
---
|
||||
|
||||
## 四、Git 工作流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 开发环境 (本地) │
|
||||
│ feature/mzl-dev 分支 │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│ 开发、测试
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 合并到 master │
|
||||
│ git merge feature/mzl-dev │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│ 推送到远程
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 生产服务器拉取 │
|
||||
│ ssh root@45.153.130.80 │
|
||||
│ git pull origin master │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│ 重新构建部署
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 生产环境更新完成 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 日常开发命令
|
||||
|
||||
```bash
|
||||
# 1. 开发环境:在 feature/mzl-dev 分支工作
|
||||
git checkout feature/mzl-dev
|
||||
git pull origin feature/mzl-dev
|
||||
# ... 开发、提交 ...
|
||||
git add .
|
||||
git commit -m "feat: xxx"
|
||||
git push origin feature/mzl-dev
|
||||
|
||||
# 2. 发布上线:合并到 master
|
||||
git checkout master
|
||||
git pull origin master
|
||||
git merge feature/mzl-dev --no-edit
|
||||
git push origin master
|
||||
git checkout feature/mzl-dev # 切回开发分支
|
||||
|
||||
# 3. 生产服务器:拉取并部署
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/x-server-mobile
|
||||
git pull origin master
|
||||
# 后端已在容器中,只需重启
|
||||
docker restart x-server-backend
|
||||
# 前端需重新构建
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、前端构建
|
||||
|
||||
### 开发环境
|
||||
```bash
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm run dev
|
||||
# 访问: http://localhost:5173
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
```bash
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm run build --mode production
|
||||
# 生成文件: frontend/dist/
|
||||
|
||||
# 上传到生产服务器
|
||||
rsync -avz --delete frontend/dist/ root@45.153.130.80:/www/sites/uniservice-mobile.hnxinyouhe.com/index/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、环境变量配置
|
||||
|
||||
### 开发环境 (.env)
|
||||
```env
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PASSWORD=mysql_xEsdPa
|
||||
```
|
||||
|
||||
### 生产环境 (.env.production)
|
||||
```env
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
DB_HOST=1Panel-mysql-prod-xxxx
|
||||
DB_PASSWORD=strong_production_password
|
||||
```
|
||||
|
||||
**注意**:生产环境密码和密钥不要提交到代码仓库!
|
||||
|
||||
---
|
||||
|
||||
## 七、常见操作错误
|
||||
|
||||
### ❌ 错误操作
|
||||
1. 在 `master` 分支直接开发新功能
|
||||
2. 在开发环境修改生产数据库
|
||||
3. 用开发域名 `xsm.dev.hnxinyouhe.com` 配置飞书开放平台
|
||||
4. 将生产环境 `.env.production` 提交到 git
|
||||
5. 忘记合并到 master 就让生产服务器拉取
|
||||
|
||||
### ✅ 正确操作
|
||||
1. 始终在 `feature/mzl-dev` 分支开发
|
||||
2. 开发完成后合并到 `master`
|
||||
3. 生产服务器只拉取 `master` 分支
|
||||
4. 敏感配置使用环境变量,不提交到代码
|
||||
5. 飞书开放平台配置生产环境域名
|
||||
|
||||
---
|
||||
|
||||
## 八、调试飞书登录
|
||||
|
||||
### 开发环境调试
|
||||
```bash
|
||||
# 1. 确保开发服务器运行
|
||||
cd /www/x-server-mobile/frontend
|
||||
npm run dev
|
||||
|
||||
# 2. 确保后端运行
|
||||
docker logs x-server-backend -f
|
||||
|
||||
# 3. 确保内网穿透运行
|
||||
frpc -c /www/x-server-mobile/frpc/frpc-dev.ini
|
||||
|
||||
# 4. 访问环境检测页
|
||||
https://xsm.dev.hnxinyouhe.com/feishu-env-test?company=2
|
||||
|
||||
# 5. 访问登录页
|
||||
https://xsm.dev.hnxinyouhe.com/login?company=2
|
||||
```
|
||||
|
||||
### 生产环境测试
|
||||
```bash
|
||||
# 直接访问生产域名
|
||||
https://uniservice-mobile.hnxinyouhe.com/login?company=2
|
||||
|
||||
# 查看生产后端日志
|
||||
ssh root@45.153.130.80
|
||||
docker logs x-server-backend -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、部署检查清单
|
||||
|
||||
上线前检查:
|
||||
|
||||
- [ ] 代码已合并到 `master` 分支
|
||||
- [ ] 前端已执行 `npm run build --mode production`
|
||||
- [ ] 生产服务器已拉取最新代码 (`git pull origin master`)
|
||||
- [ ] 后端容器已重启 (`docker restart x-server-backend`)
|
||||
- [ ] 前端静态文件已上传到生产服务器
|
||||
- [ ] 飞书开放平台配置的是生产环境域名
|
||||
- [ ] 环境变量配置正确(数据库、Redis、密钥等)
|
||||
|
||||
---
|
||||
|
||||
## 十、快速参考
|
||||
|
||||
### 环境判断
|
||||
|
||||
```typescript
|
||||
// 前端判断开发/生产环境
|
||||
const isDev = import.meta.env.DEV
|
||||
const isProd = import.meta.env.PROD
|
||||
|
||||
// 后端判断(PHP)
|
||||
$appEnv = config('app.env'); // local, production
|
||||
$isDebug = config('app.debug'); // true, false
|
||||
```
|
||||
|
||||
### API 地址
|
||||
|
||||
```typescript
|
||||
// 开发环境:通过代理访问
|
||||
const API_BASE = '/api/v1'
|
||||
|
||||
// 生产环境:同样通过代理访问(OpenResty)
|
||||
const API_BASE = '/api/v1'
|
||||
```
|
||||
|
||||
### 回调地址
|
||||
|
||||
```typescript
|
||||
// 开发环境(调试用)
|
||||
const CALLBACK_URL = 'https://xsm.dev.hnxinyouhe.com/login/callback'
|
||||
|
||||
// 生产环境(正式)
|
||||
const CALLBACK_URL = 'https://uniservice-mobile.hnxinyouhe.com/login/callback'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-02-28
|
||||
@@ -0,0 +1,321 @@
|
||||
# Git 工作流程
|
||||
|
||||
## 分支说明
|
||||
|
||||
| 分支 | 用途 | 部署环境 |
|
||||
|------|------|---------|
|
||||
| `master` | 生产分支 | 线上生产环境 (45.153.130.80) |
|
||||
| `develop` | 开发集成分支 | 测试/预发布环境 |
|
||||
| `feature/*` | 个人功能分支 | 本地开发环境 |
|
||||
|
||||
## 分支结构
|
||||
|
||||
```
|
||||
master (生产)
|
||||
↑
|
||||
发布合并
|
||||
↑
|
||||
develop (开发)
|
||||
↑
|
||||
功能合并
|
||||
↑
|
||||
┌──────────────┬────┴────┬──────────────┐
|
||||
↓ ↓ ↓ ↓
|
||||
feature/xxx-1 feature/xxx-2 feature/xxx-3 feature/xxx-4
|
||||
(个人A) (个人B) (个人A) (个人B)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 一、工作流程
|
||||
|
||||
### 1.1 开发新功能
|
||||
|
||||
**从 develop 创建个人功能分支:**
|
||||
|
||||
```bash
|
||||
# 确保本地 develop 是最新的
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
# 创建个人功能分支(命名规范:feature/功能名 或 feature/功能名-姓名首字母)
|
||||
git checkout -b feature/user-login
|
||||
# 或带姓名标识
|
||||
git checkout -b feature/user-login-mzl
|
||||
```
|
||||
|
||||
**在功能分支上开发:**
|
||||
|
||||
```bash
|
||||
# 开发、提交
|
||||
git add .
|
||||
git commit -m "feat: add user login"
|
||||
git push origin feature/user-login
|
||||
|
||||
# 继续开发...
|
||||
git add .
|
||||
git commit -m "fix: correct login error handling"
|
||||
git push origin feature/user-login
|
||||
```
|
||||
|
||||
### 1.2 功能开发完成
|
||||
|
||||
**合并到 develop 进行团队测试:**
|
||||
|
||||
```bash
|
||||
# 1. 切换到 develop 并更新
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
# 2. 合并功能分支(使用 --no-ff 保留合并历史)
|
||||
git merge --no-ff feature/user-login -m "Merge feature/user-login into develop"
|
||||
|
||||
# 3. 推送到远程
|
||||
git push origin develop
|
||||
|
||||
# 4. (可选)删除已合并的功能分支
|
||||
git branch -d feature/user-login
|
||||
git push origin --delete feature/user-login
|
||||
```
|
||||
|
||||
### 1.3 发布到生产
|
||||
|
||||
**从 develop 合并到 master:**
|
||||
|
||||
```bash
|
||||
# 1. 切换到 master 并更新
|
||||
git checkout master
|
||||
git pull origin master
|
||||
|
||||
# 2. 合并 develop(使用 --no-ff 保留合并历史)
|
||||
git merge --no-ff develop -m "Release: merge develop into master"
|
||||
|
||||
# 3. 添加版本标签(可选)
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0"
|
||||
git push origin v1.0.0
|
||||
|
||||
# 4. 推送到远程
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### 1.4 生产服务器部署
|
||||
|
||||
```bash
|
||||
ssh root@45.153.130.80
|
||||
cd /opt/x-server-mobile
|
||||
git pull origin master
|
||||
docker restart x-server-backend
|
||||
# 或
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、分支命名规范
|
||||
|
||||
| 分支类型 | 命名格式 | 示例 |
|
||||
|---------|---------|------|
|
||||
| 功能分支 | `feature/功能名` 或 `feature/功能名-姓名` | `feature/user-login`, `feature/user-login-mzl` |
|
||||
| 修复分支 | `fix/问题描述` 或 `fix/问题描述-姓名` | `fix/login-error`, `fix/login-error-mzl` |
|
||||
| 热修复分支 | `hotfix/问题描述` | `hotfix/security-fix` |
|
||||
|
||||
---
|
||||
|
||||
## 三、前端部署
|
||||
|
||||
```bash
|
||||
# 1. 切换到 master
|
||||
git checkout master
|
||||
git pull origin master
|
||||
|
||||
# 2. 构建前端
|
||||
cd frontend
|
||||
npm run build --mode production
|
||||
|
||||
# 3. 上传到服务器
|
||||
rsync -avz --delete frontend/dist/ root@45.153.130.80:/www/sites/uniservice-mobile.hnxinyouhe.com/index/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、提交信息规范
|
||||
|
||||
| 类型 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| `feat` | 新功能 | `feat: add user login` |
|
||||
| `fix` | 修复bug | `fix: correct i18n loading` |
|
||||
| `docs` | 文档变更 | `docs: update deployment guide` |
|
||||
| `style` | 代码格式 | `style: format code` |
|
||||
| `refactor` | 重构 | `refactor: simplify auth logic` |
|
||||
| `test` | 测试相关 | `test: add login test` |
|
||||
| `chore` | 构建/工具 | `chore: update dependencies` |
|
||||
|
||||
**完整格式:**
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
**示例:**
|
||||
```
|
||||
feat(login): add feishu auto-login support
|
||||
|
||||
- Add H5 JSSDK integration
|
||||
- Implement tt.requestAuthCode for silent login
|
||||
- Add token auto-refresh on 401
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、快速发布脚本
|
||||
|
||||
### 5.1 功能合并到 develop
|
||||
|
||||
```bash
|
||||
# 添加到 ~/.bashrc 或 ~/.zshrc
|
||||
git-finish() {
|
||||
local branch=$(git branch --show-current)
|
||||
if [[ $branch != feature/* ]]; then
|
||||
echo "❌ 当前不在 feature 分支上"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "=== 合并 $branch 到 develop ==="
|
||||
git checkout develop && \
|
||||
git pull origin develop && \
|
||||
git merge --no-ff $branch -m "Merge $branch into develop" && \
|
||||
git push origin develop && \
|
||||
echo "✅ 完成,可删除功能分支: git branch -d $branch"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 发布到 master
|
||||
|
||||
```bash
|
||||
# 添加到 ~/.bashrc 或 ~/.zshrc
|
||||
git-release() {
|
||||
echo "=== 发布 develop 到 master ==="
|
||||
git checkout master && \
|
||||
git pull origin master && \
|
||||
git merge --no-ff develop -m "Release: merge develop into master" && \
|
||||
git push origin master && \
|
||||
git checkout develop && \
|
||||
echo "✅ 发布完成,请部署生产环境"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、协作场景
|
||||
|
||||
### 6.1 多人同时开发
|
||||
|
||||
```
|
||||
时间线:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ A 开发 feature/login │
|
||||
│ B 开发 feature/dashboard │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ A 完成,合并 feature/login 到 develop │
|
||||
│ B 继续开发 feature/dashboard │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ B 完成,合并 feature/dashboard 到 develop │
|
||||
│ (此时 develop 包含 A 和 B 的更改) │
|
||||
└───────────────────────────┬─────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 在 develop 上测试通过后,合并到 master 发布 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 处理冲突
|
||||
|
||||
```bash
|
||||
# 合并时遇到冲突
|
||||
git checkout develop
|
||||
git merge feature/login
|
||||
|
||||
# Git 提示冲突
|
||||
# Auto-merging src/login.tsx
|
||||
# CONFLICT (content): Merge conflict in src/login.tsx
|
||||
|
||||
# 手动解决冲突后
|
||||
git add src/login.tsx
|
||||
git commit -m "Merge feature/login into develop (resolved conflicts)"
|
||||
git push origin develop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、远程仓库
|
||||
|
||||
- **仓库地址**:http://219.157.255.213:25311/xinyouhe/x-server-mobile.git
|
||||
- **生产分支**:`master`
|
||||
- **开发分支**:`develop`
|
||||
- **个人分支**:`feature/*`
|
||||
|
||||
---
|
||||
|
||||
## 八、最佳实践
|
||||
|
||||
### ✅ 推荐做法
|
||||
|
||||
1. **保持分支简短** - 功能分支完成后及时合并并删除
|
||||
2. **频繁提交** - 小步提交,便于代码审查和回滚
|
||||
3. **写好提交信息** - 清晰描述做了什么
|
||||
4. **推送前先拉取** - 避免不必要的冲突
|
||||
5. **代码审查** - 合并前让团队成员审查代码
|
||||
|
||||
### ❌ 避免做法
|
||||
|
||||
1. **直接在 master/develop 上开发** - 始终使用功能分支
|
||||
2. **长时间不合并** - 功能分支会越来越难合并
|
||||
3. **提交敏感信息** - 密钥、配置等不要提交
|
||||
4. **强制推送 master/develop** - 可能丢失他人代码
|
||||
|
||||
---
|
||||
|
||||
## 九、常用命令速查
|
||||
|
||||
```bash
|
||||
# 查看分支状态
|
||||
git status
|
||||
git branch -vv
|
||||
|
||||
# 创建功能分支
|
||||
git checkout develop && git pull
|
||||
git checkout -b feature/xxx
|
||||
|
||||
# 合并功能分支
|
||||
git checkout develop
|
||||
git merge --no-ff feature/xxx
|
||||
|
||||
# 发布到生产
|
||||
git checkout master
|
||||
git merge --no-ff develop
|
||||
|
||||
# 删除已合并分支
|
||||
git branch -d feature/xxx
|
||||
git push origin --delete feature/xxx
|
||||
|
||||
# 查看差异
|
||||
git diff develop master
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-02-28
|
||||
@@ -0,0 +1,287 @@
|
||||
# X-Server Mobile 快速部署指南
|
||||
|
||||
## 一、服务器准备
|
||||
|
||||
### 1.1 安装必要软件
|
||||
|
||||
```bash
|
||||
# 更新系统
|
||||
apt-get update && apt-get upgrade -y
|
||||
|
||||
# 安装 certbot(SSL 证书)
|
||||
apt-get install certbot -y
|
||||
|
||||
# 安装 rsync(文件同步)
|
||||
apt-get install rsync -y
|
||||
```
|
||||
|
||||
### 1.2 创建部署目录
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/x-server-mobile/{frontend,backend,logs,backup}
|
||||
mkdir -p /opt/x-server-mobile/logs/{backend,nginx}
|
||||
```
|
||||
|
||||
### 1.3 获取 SSL 证书
|
||||
|
||||
```bash
|
||||
# 停止 OpenResty(如果占用 80 端口)
|
||||
systemctl stop openresty
|
||||
|
||||
# 获取证书
|
||||
certbot certonly --standalone -d xsm.hnxinyouhe.com
|
||||
|
||||
# 重新启动 OpenResty
|
||||
systemctl start openresty
|
||||
```
|
||||
|
||||
### 1.4 准备数据库
|
||||
|
||||
```bash
|
||||
# 创建数据库用户
|
||||
docker exec -it <mysql-container> mysql -uroot -p
|
||||
|
||||
# 在 MySQL 中执行:
|
||||
CREATE USER 'xserver'@'%' IDENTIFIED BY 'your_strong_password';
|
||||
GRANT ALL PRIVILEGES ON xserver.* TO 'xserver'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
# 导入数据库(如果有备份)
|
||||
docker exec -i <mysql-container> mysql -uxserver -pyour_password xserver < backup.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、配置文件准备
|
||||
|
||||
### 2.1 环境变量
|
||||
|
||||
```bash
|
||||
# 在项目根目录
|
||||
cp deploy/.env.production.template .env.production
|
||||
|
||||
# 编辑填写实际配置
|
||||
vi .env.production
|
||||
```
|
||||
|
||||
### 2.2 更新 docker-compose.prod.yml
|
||||
|
||||
```yaml
|
||||
# 修改以下配置为实际值:
|
||||
- DB_HOST=1Panel-mysql-xxxx # 实际 MySQL 容器名
|
||||
- DB_PASSWORD=your_password # 实际密码
|
||||
- REDIS_HOST=1Panel-redis-xxxx # 实际 Redis 容器名
|
||||
- REDIS_PASSWORD=your_redis_password # 实际 Redis 密码
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、部署
|
||||
|
||||
### 3.1 方式一:使用部署脚本(推荐)
|
||||
|
||||
```bash
|
||||
# 1. 构建前端
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
|
||||
# 2. 执行部署脚本
|
||||
./scripts/deploy.sh your-server-ip
|
||||
|
||||
# 脚本会自动完成:
|
||||
# - 备份当前版本
|
||||
# - 上传前端和后端
|
||||
# - 重启容器
|
||||
# - 重载 OpenResty
|
||||
```
|
||||
|
||||
### 3.2 方式二:手动部署
|
||||
|
||||
```bash
|
||||
# 1. 构建前端
|
||||
cd frontend && npm run build && cd ..
|
||||
|
||||
# 2. 上传前端
|
||||
rsync -avz --delete frontend/dist/ root@server:/opt/x-server-mobile/frontend/
|
||||
|
||||
# 3. 上传后端
|
||||
rsync -avz --exclude='vendor' --exclude='runtime' backend/ root@server:/opt/x-server-mobile/backend/
|
||||
|
||||
# 4. 上传配置文件
|
||||
scp deploy/docker-compose.prod.yml root@server:/opt/x-server-mobile/
|
||||
scp deploy/nginx/x-server-mobile-prod.conf root@server:/tmp/
|
||||
|
||||
# 5. 登录服务器配置 OpenResty
|
||||
ssh root@server
|
||||
cp /tmp/x-server-mobile-prod.conf /usr/local/openresty/nginx/conf/conf.d/x-server-mobile.conf
|
||||
openresty -t && openresty -s reload
|
||||
|
||||
# 6. 启动后端容器
|
||||
cd /opt/x-server-mobile
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、验证部署
|
||||
|
||||
### 4.1 检查容器状态
|
||||
|
||||
```bash
|
||||
docker ps | grep x-server
|
||||
docker logs -f x-server-backend-prod
|
||||
```
|
||||
|
||||
### 4.2 检查服务
|
||||
|
||||
```bash
|
||||
# 检查前端
|
||||
curl -I https://xsm.hnxinyouhe.com
|
||||
|
||||
# 检查 API
|
||||
curl https://xsm.hnxinyouhe.com/api/v1/user/info \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### 4.3 功能测试
|
||||
|
||||
- [ ] 登录页面正常访问
|
||||
- [ ] 邮箱密码登录成功
|
||||
- [ ] 飞书免登成功
|
||||
- [ ] 审批列表正常显示
|
||||
- [ ] 飞书卡片通知正常
|
||||
|
||||
---
|
||||
|
||||
## 五、常见问题
|
||||
|
||||
### Q1: 容器无法启动
|
||||
|
||||
```bash
|
||||
# 查看详细日志
|
||||
docker logs x-server-backend-prod
|
||||
|
||||
# 检查网络
|
||||
docker network ls | grep 1panel
|
||||
docker network inspect 1panel-network
|
||||
|
||||
# 检查环境变量
|
||||
docker exec x-server-backend-prod env | grep DB_
|
||||
```
|
||||
|
||||
### Q2: API 返回 500
|
||||
|
||||
```bash
|
||||
# 查看后端日志
|
||||
docker logs x-server-backend-prod --tail 50
|
||||
|
||||
# 检查数据库连接
|
||||
docker exec x-server-backend-prod php -r "
|
||||
var_dump(getenv('DB_HOST'));
|
||||
var_dump(getenv('DB_DATABASE'));
|
||||
"
|
||||
|
||||
# 进入容器调试
|
||||
docker exec -it x-server-backend-prod bash
|
||||
```
|
||||
|
||||
### Q3: SSL 证书问题
|
||||
|
||||
```bash
|
||||
# 检查证书路径
|
||||
ls -la /etc/letsencrypt/live/xsm.hnxinyouhe.com/
|
||||
|
||||
# 测试证书
|
||||
openssl s_client -connect xsm.hnxinyouhe.com:443 -servername xsm.hnxinyouhe.com
|
||||
|
||||
# 手动续期
|
||||
certbot renew --force-renewal
|
||||
```
|
||||
|
||||
### Q4: 前端刷新 404
|
||||
|
||||
检查 OpenResty 配置中的 `try_files` 指令:
|
||||
```nginx
|
||||
location / {
|
||||
root /opt/x-server-mobile/frontend;
|
||||
try_files $uri $uri/ /index.html; # 确保有这行
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、回滚
|
||||
|
||||
```bash
|
||||
# 查看可用备份
|
||||
ssh root@server "ls -la /opt/x-server-mobile/backup/"
|
||||
|
||||
# 执行回滚
|
||||
./scripts/rollback.sh 20240227_150000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、监控命令
|
||||
|
||||
```bash
|
||||
# 实时日志
|
||||
docker logs -f x-server-backend-prod
|
||||
|
||||
# 容器资源
|
||||
docker stats x-server-backend-prod
|
||||
|
||||
# Nginx 访问日志
|
||||
tail -f /opt/x-server-mobile/logs/nginx_access.log
|
||||
|
||||
# Nginx 错误日志
|
||||
tail -f /opt/x-server-mobile/logs/nginx_error.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、更新部署
|
||||
|
||||
当代码有更新时:
|
||||
|
||||
```bash
|
||||
# 1. 拉取最新代码
|
||||
git pull
|
||||
|
||||
# 2. 构建前端
|
||||
cd frontend && npm run build && cd ..
|
||||
|
||||
# 3. 部署
|
||||
./scripts/deploy.sh your-server-ip
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置检查清单
|
||||
|
||||
部署前确认:
|
||||
|
||||
```bash
|
||||
# 1. 检查环境变量
|
||||
cat .env.production | grep -v "^#" | grep -v "^$"
|
||||
|
||||
# 2. 检查构建产物
|
||||
ls -la frontend/dist/
|
||||
|
||||
# 3. 检查 OpenResty 配置
|
||||
cat deploy/nginx/x-server-mobile-prod.conf | grep server_name
|
||||
|
||||
# 4. 测试 SSH 连接
|
||||
ssh root@your-server "echo 'SSH OK'"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 联系支持
|
||||
|
||||
如有问题,请参考完整文档:
|
||||
- `DEPLOYMENT.md` - 完整部署文档
|
||||
- `DEPLOYMENT_CHECKLIST.md` - 部署检查清单
|
||||
- `PROJECT_ISSUES.md` - 问题汇总
|
||||
@@ -0,0 +1,142 @@
|
||||
# 反向代理配置指南
|
||||
|
||||
本指南用于配置 OpenResty 和 frpc 以将 API 暴露到公网,便于调试飞书登录。
|
||||
|
||||
## 环境要求
|
||||
|
||||
- 已安装 OpenResty 或 Nginx
|
||||
- 已安装 frpc
|
||||
- 拥有可用的 frp 服务器
|
||||
- 拥有可配置的域名
|
||||
|
||||
## 安装步骤
|
||||
|
||||
### 1. 安装 OpenResty (Ubuntu/Debian)
|
||||
|
||||
```bash
|
||||
# 导入 GPG 密钥
|
||||
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
|
||||
|
||||
# 添加 OpenResty 仓库
|
||||
sudo apt-get -y install -y wget gnupg ca-certificates
|
||||
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
|
||||
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
|
||||
|
||||
# 安装 OpenResty
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openresty
|
||||
|
||||
# 启动服务
|
||||
sudo systemctl start openresty
|
||||
sudo systemctl enable openresty
|
||||
```
|
||||
|
||||
### 2. 配置 OpenResty
|
||||
|
||||
将 `nginx/x-server-api.conf` 复制到 OpenResty 配置目录:
|
||||
|
||||
```bash
|
||||
sudo cp nginx/x-server-api.conf /usr/local/openresty/nginx/conf/conf.d/
|
||||
sudo mkdir -p /usr/local/openresty/nginx/logs
|
||||
sudo openresty -s reload
|
||||
```
|
||||
|
||||
### 3. 安装 frpc
|
||||
|
||||
```bash
|
||||
# 下载 frpc(根据你的系统选择版本)
|
||||
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
|
||||
|
||||
# 解压
|
||||
tar xzf frp_0.52.3_linux_amd64.tar.gz
|
||||
cd frp_0.52.3_linux_amd64
|
||||
|
||||
# 复制到系统路径
|
||||
sudo cp frpc /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/frpc
|
||||
```
|
||||
|
||||
### 4. 配置 frpc
|
||||
|
||||
编辑 `frpc/frpc.ini`,填入你的 frp 服务器信息:
|
||||
|
||||
```ini
|
||||
[common]
|
||||
server_addr = your-frp-server.com # 你的 frp 服务器地址
|
||||
server_port = 7000 # frp 服务器端口
|
||||
token = your-frp-token # 认证令牌
|
||||
|
||||
[x-server-api]
|
||||
type = http
|
||||
local_ip = 127.0.0.1
|
||||
local_port = 8787
|
||||
custom_domains = api.x-server.your-domain.com # 你的公网域名
|
||||
```
|
||||
|
||||
### 5. 启动 frpc
|
||||
|
||||
```bash
|
||||
# 前台运行(测试)
|
||||
frpc -c frpc/frpc.ini
|
||||
|
||||
# 后台运行(生产)
|
||||
nohup frpc -c frpc/frpc.ini > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
### 6. 配置 DNS
|
||||
|
||||
将你的域名 `api.x-server.your-domain.com` 的 A 记录指向你的 frp 服务器 IP。
|
||||
|
||||
### 7. 配置飞书应用
|
||||
|
||||
在飞书开放平台配置回调 URL:
|
||||
|
||||
```
|
||||
https://api.x-server.your-domain.com/api/v1/auth/feishu-login
|
||||
```
|
||||
|
||||
## 验证配置
|
||||
|
||||
### 测试本地 API
|
||||
|
||||
```bash
|
||||
curl http://localhost:8787/api/v1/user/info
|
||||
```
|
||||
|
||||
### 测试反向代理
|
||||
|
||||
```bash
|
||||
curl http://api.x-server.local/api/v1/user/info
|
||||
```
|
||||
|
||||
### 测试公网访问
|
||||
|
||||
```bash
|
||||
curl https://api.x-server.your-domain.com/api/v1/user/info
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### frpc 连接失败
|
||||
|
||||
1. 检查 frp 服务器是否在线
|
||||
2. 检查 token 是否正确
|
||||
3. 检查端口是否被防火墙阻止
|
||||
|
||||
### 域名无法访问
|
||||
|
||||
1. 检查 DNS 解析是否生效
|
||||
2. 检查 frp 服务器是否配置了该域名
|
||||
3. 检查 frpc 日志
|
||||
|
||||
### CORS 错误
|
||||
|
||||
如果前端调用 API 时出现 CORS 错误,检查 nginx 配置中的 CORS 头部设置。
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **生产环境务必使用 HTTPS**
|
||||
2. 配置 IP 白名单限制访问
|
||||
3. 使用强密码和 token
|
||||
4. 定期更新 frp 和 OpenResty 版本
|
||||
5. 配置防火墙规则
|
||||
@@ -0,0 +1,598 @@
|
||||
# X-Server Mobile 线上部署方案
|
||||
|
||||
## 线上环境
|
||||
|
||||
- **面板**: 1Panel (Docker 管理)
|
||||
- **Web 服务器**: OpenResty
|
||||
- **数据库**: MySQL (容器)
|
||||
- **缓存**: Redis (容器)
|
||||
- **域名**: `xsm.hnxinyouhe.com` (待配置)
|
||||
|
||||
---
|
||||
|
||||
## 架构设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ OpenResty (80/443) │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 静态资源托管 │ │
|
||||
│ │ /frontend/dist/* │ │
|
||||
│ │ SPA Router fallback │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ API 反向代理 │ │
|
||||
│ │ /api/* → localhost:8787 │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 飞书回调代理 │ │
|
||||
│ │ /login/* → localhost:8787 │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
▼ ▼ ▼
|
||||
┌───────────┐ ┌───────────┐ ┌───────────┐
|
||||
│ 后端 │ │ MySQL │ │ Redis │
|
||||
│ :8787 │ │ :3306 │ │ :6379 │
|
||||
│ Docker │ │ 1Panel │ │ 1Panel │
|
||||
└───────────┘ └───────────┘ └───────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 第一步:准备线上目录结构
|
||||
|
||||
```bash
|
||||
# 在服务器上创建部署目录
|
||||
mkdir -p /opt/x-server-mobile
|
||||
mkdir -p /opt/x-server-mobile/frontend
|
||||
mkdir -p /opt/x-server-mobile/backend
|
||||
mkdir -p /opt/x-server-mobile/logs
|
||||
mkdir -p /opt/x-server-mobile/backup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第二步:前端部署
|
||||
|
||||
#### 2.1 本地构建
|
||||
|
||||
```bash
|
||||
# 在开发环境
|
||||
cd /www/x-server-mobile/frontend
|
||||
|
||||
# 安装依赖(如果需要)
|
||||
npm install
|
||||
|
||||
# 构建生产版本
|
||||
npm run build
|
||||
|
||||
# 生成的文件在 frontend/dist/ 目录
|
||||
```
|
||||
|
||||
#### 2.2 上传静态文件
|
||||
|
||||
```bash
|
||||
# 方式1:使用 scp 上传
|
||||
scp -r frontend/dist/* root@your-server:/opt/x-server-mobile/frontend/
|
||||
|
||||
# 方式2:使用 rsync 同步
|
||||
rsync -avz --delete frontend/dist/ root@your-server:/opt/x-server-mobile/frontend/
|
||||
```
|
||||
|
||||
#### 2.3 构建环境配置
|
||||
|
||||
创建 `frontend/.env.production`:
|
||||
|
||||
```env
|
||||
# API 地址(使用相对路径,由 OpenResty 代理)
|
||||
VITE_API_BASE=/api/v1
|
||||
|
||||
# 或使用绝对地址(如果前后端分离部署)
|
||||
# VITE_API_BASE=https://api.xsm.hnxinyouhe.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第三步:后端部署
|
||||
|
||||
#### 3.1 创建生产环境 Docker Compose
|
||||
|
||||
**文件**: `/opt/x-server-mobile/deploy/docker-compose.prod.yml`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: x-server-backend-prod
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8787:8787"
|
||||
environment:
|
||||
# 生产环境配置
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
|
||||
# 数据库配置(使用 1Panel 的 MySQL)
|
||||
- DB_HOST=1Panel-mysql-xxxx # 替换为实际容器名
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=xserver
|
||||
- DB_USERNAME=xserver # 建议创建专用数据库用户
|
||||
- DB_PASSWORD=your_password # 强密码
|
||||
|
||||
# Redis 配置(使用 1Panel 的 Redis)
|
||||
- REDIS_HOST=1Panel-redis-xxxx # 替换为实际容器名
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=your_redis_password
|
||||
|
||||
# 飞书配置
|
||||
- FEISHU_APP_ID=cli_xxxxxxxxxxxxx
|
||||
- FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
|
||||
- FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx
|
||||
- FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx
|
||||
- FEISHU_TENANT_KEY=xxxxxxxxxxxxxxxxxxxx
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
- ./logs/app:/app/runtime/logs
|
||||
networks:
|
||||
- 1panel-network
|
||||
healthcheck:
|
||||
test: ["CMD", "php", "-r", "exit(0);"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
```
|
||||
|
||||
#### 3.2 创建生产环境后端配置
|
||||
|
||||
**后端 OPcache 配置** (`deploy/php-prod.ini`):
|
||||
|
||||
```ini
|
||||
# 生产环境 OPcache 配置
|
||||
opcache.enable=1
|
||||
opcache.memory_consumption=128
|
||||
opcache.interned_strings_buffer=8
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=60
|
||||
opcache.fast_shutdown=1
|
||||
opcache.enable_cli=1
|
||||
|
||||
# 禁用错误显示
|
||||
display_errors=0
|
||||
display_startup_errors=0
|
||||
log_errors=1
|
||||
error_log=/app/runtime/logs/php_errors.log
|
||||
```
|
||||
|
||||
#### 3.3 更新 Dockerfile
|
||||
|
||||
```dockerfile
|
||||
FROM php:8.5-cli
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
unzip \
|
||||
git \
|
||||
libzip-dev \
|
||||
libpng-dev \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install PHP extensions
|
||||
RUN docker-php-ext-install zip pdo pdo_mysql bcmath pcntl opcache
|
||||
|
||||
# Install Composer
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy composer files
|
||||
COPY composer.json composer.lock* ./
|
||||
|
||||
# Install dependencies
|
||||
RUN composer install --no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
# Copy application files
|
||||
COPY . .
|
||||
|
||||
# Copy PHP configuration
|
||||
COPY php-prod.ini /usr/local/etc/php/conf.d/99-production.ini
|
||||
|
||||
# Create runtime directories
|
||||
RUN mkdir -p /app/runtime/logs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8787
|
||||
|
||||
# Start webman in foreground mode
|
||||
CMD ["php", "start.php", "start"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第四步:OpenResty 配置
|
||||
|
||||
#### 4.1 站点配置
|
||||
|
||||
**文件**: `/usr/local/openresty/nginx/conf/conf.d/x-server-mobile.conf`
|
||||
|
||||
```nginx
|
||||
# X-Server Mobile 线上环境配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name xsm.hnxinyouhe.com;
|
||||
|
||||
# 强制 HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name xsm.hnxinyouhe.com;
|
||||
|
||||
# SSL 证书配置(使用 Let's Encrypt 或自签名)
|
||||
ssl_certificate /etc/nginx/ssl/xsm.hnxinyouhe.com.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/xsm.hnxinyouhe.com.key;
|
||||
|
||||
# SSL 安全配置
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# 日志
|
||||
access_log /opt/x-server-mobile/logs/nginx_access.log;
|
||||
error_log /opt/x-server-mobile/logs/nginx_error.log;
|
||||
|
||||
# Gzip 压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
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 ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf|eot)$ {
|
||||
root /opt/x-server-mobile/frontend;
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 飞书回调(必须在 API 之前配置)
|
||||
location /login {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
}
|
||||
|
||||
location /login/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
}
|
||||
|
||||
location /login/qrcode {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
}
|
||||
|
||||
# 飞书卡片回调
|
||||
location /feishu/card/callback {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8787;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Host $host;
|
||||
|
||||
# 超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# 前端 SPA(所有其他请求返回 index.html)
|
||||
location / {
|
||||
root /opt/x-server-mobile/frontend;
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 配置说明
|
||||
|
||||
1. **静态资源**: 直接由 OpenResty 托管,7天缓存
|
||||
2. **API 请求**: 代理到后端 8787 端口
|
||||
3. **飞书回调**: 特殊路径直接代理到后端
|
||||
4. **SPA 路由**: 所有其他请求返回 index.html
|
||||
|
||||
---
|
||||
|
||||
### 第五步:数据库准备
|
||||
|
||||
#### 5.1 创建数据库和用户
|
||||
|
||||
```sql
|
||||
-- 创建专用数据库用户
|
||||
CREATE USER 'xserver'@'%' IDENTIFIED BY 'your_strong_password';
|
||||
|
||||
-- 授予权限
|
||||
GRANT ALL PRIVILEGES ON xserver.* TO 'xserver'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- 如果数据库不存在,创建并导入结构
|
||||
CREATE DATABASE IF NOT EXISTS xserver CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
#### 5.2 数据库迁移
|
||||
|
||||
```bash
|
||||
# 从开发环境导出数据
|
||||
docker exec 1Panel-mysql-409s mysqldump -uroot -pmysql_xEsdPa xserver > xserver_backup.sql
|
||||
|
||||
# 导入到线上数据库
|
||||
docker exec -i 1Panel-mysql-xxxx mysql -uxserver -pyour_password xserver < xserver_backup.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第六步:SSL 证书配置
|
||||
|
||||
#### 6.1 使用 Let's Encrypt(推荐)
|
||||
|
||||
```bash
|
||||
# 安装 certbot
|
||||
apt-get install certbot
|
||||
|
||||
# 获取证书
|
||||
certbot certonly --standalone -d xsm.hnxinyouhe.com
|
||||
|
||||
# 证书路径
|
||||
# /etc/letsencrypt/live/xsm.hnxinyouhe.com/fullchain.pem
|
||||
# /etc/letsencrypt/live/xsm.hnxinyouhe.com/privkey.pem
|
||||
```
|
||||
|
||||
#### 6.2 自动续期
|
||||
|
||||
```bash
|
||||
# 添加 crontab
|
||||
0 3 * * * certbot renew --quiet && nginx -s reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第七步:部署流程
|
||||
|
||||
#### 开发到生产部署
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy.sh - 部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " X-Server Mobile 生产部署脚本"
|
||||
echo "========================================="
|
||||
|
||||
# 1. 备份当前版本
|
||||
echo "📦 备份当前版本..."
|
||||
ssh root@your-server "mkdir -p /opt/x-server-mobile/backup/\$(date +%Y%m%d_%H%M%S)"
|
||||
ssh root@your-server "cp -r /opt/x-server-mobile/frontend /opt/x-server-mobile/backup/\$(date +%Y%m%d_%H%M%S)/"
|
||||
|
||||
# 2. 构建前端
|
||||
echo "🔨 构建前端..."
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# 3. 上传前端
|
||||
echo "📤 上传前端..."
|
||||
rsync -avz --delete dist/ root@your-server:/opt/x-server-mobile/frontend/
|
||||
|
||||
# 4. 上传后端
|
||||
echo "📤 上传后端..."
|
||||
rsync -avz --exclude='vendor' --exclude='runtime' \
|
||||
../backend/ root@your-server:/opt/x-server-mobile/backend/
|
||||
|
||||
# 5. 重启后端容器
|
||||
echo "🔄 重启后端..."
|
||||
ssh root@your-server "cd /opt/x-server-mobile && docker-compose -f docker-compose.prod.yml restart backend"
|
||||
|
||||
# 6. 重载 OpenResty
|
||||
echo "🔄 重载 OpenResty..."
|
||||
ssh root@your-server "openresty -s reload"
|
||||
|
||||
echo "✅ 部署完成!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第八步:监控和日志
|
||||
|
||||
#### 8.1 日志位置
|
||||
|
||||
```bash
|
||||
# Nginx 访问日志
|
||||
/opt/x-server-mobile/logs/nginx_access.log
|
||||
|
||||
# Nginx 错误日志
|
||||
/opt/x-server-mobile/logs/nginx_error.log
|
||||
|
||||
# 后端应用日志
|
||||
docker logs x-server-backend-prod -f
|
||||
|
||||
# 后端运行时日志
|
||||
/opt/x-server-mobile/logs/app/
|
||||
```
|
||||
|
||||
#### 8.2 监控命令
|
||||
|
||||
```bash
|
||||
# 检查后端容器状态
|
||||
docker ps | grep x-server-backend-prod
|
||||
|
||||
# 检查后端健康
|
||||
curl http://127.0.0.1:8787/
|
||||
|
||||
# 检查数据库连接
|
||||
docker exec x-server-backend-prod php -r "var_dump(getenv('DB_HOST'));"
|
||||
|
||||
# 查看 PHP OPcache 状态
|
||||
# 需要在后端添加 OPcache 状态页面
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第九步:安全加固
|
||||
|
||||
#### 9.1 防火墙配置
|
||||
|
||||
```bash
|
||||
# 只开放必要端口
|
||||
ufw allow 22 # SSH
|
||||
ufw allow 80 # HTTP
|
||||
ufw allow 443 # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
#### 9.2 PHP 安全配置
|
||||
|
||||
```ini
|
||||
# php-prod.ini
|
||||
expose_php = Off
|
||||
allow_url_fopen = Off
|
||||
allow_url_include = Off
|
||||
disable_functions = exec,passthru,shell_exec,system,proc_open,popen
|
||||
```
|
||||
|
||||
#### 9.3 环境变量保护
|
||||
|
||||
- 不要将敏感信息提交到代码仓库
|
||||
- 使用 `.env` 文件或 Docker secrets 管理敏感信息
|
||||
- 定期轮换密码和密钥
|
||||
|
||||
---
|
||||
|
||||
### 第十步:回滚方案
|
||||
|
||||
#### 10.1 快速回滚
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# rollback.sh - 回滚脚本
|
||||
|
||||
BACKUP_DATE=$1 # 格式: 20240227_150000
|
||||
|
||||
if [ -z "$BACKUP_DATE" ]; then
|
||||
echo "请指定备份日期,格式: 20240227_150000"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔄 回滚到 $BACKUP_DATE ..."
|
||||
|
||||
# 恢复前端
|
||||
cp -r /opt/x-server-mobile/backup/$BACKUP_DATE/frontend/* /opt/x-server-mobile/frontend/
|
||||
|
||||
# 恢复后端(可选)
|
||||
# cd /opt/x-server-mobile/backend
|
||||
# git checkout <previous-commit>
|
||||
# docker-compose -f docker-compose.prod.yml restart backend
|
||||
|
||||
# 重载 OpenResty
|
||||
openresty -s reload
|
||||
|
||||
echo "✅ 回滚完成"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 检查清单
|
||||
|
||||
部署前检查:
|
||||
|
||||
- [ ] 域名 DNS 已配置指向服务器 IP
|
||||
- [ ] SSL 证书已配置
|
||||
- [ ] MySQL 数据库已创建
|
||||
- [ ] Redis 可正常连接
|
||||
- [ ] 飞书应用回调地址已更新
|
||||
- [ ] 环境变量已正确配置
|
||||
- [ ] 防火墙规则已设置
|
||||
- [ ] 日志目录已创建
|
||||
|
||||
部署后验证:
|
||||
|
||||
- [ ] 前端页面可正常访问
|
||||
- [ ] API 接口返回正常
|
||||
- [ ] 飞书登录功能正常
|
||||
- [ ] 审批流程功能正常
|
||||
- [ ] 日志输出正常
|
||||
- [ ] 容器健康检查通过
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 前端刷新 404
|
||||
|
||||
**原因**: OpenResty 配置没有正确处理 SPA 路由
|
||||
|
||||
**解决**: 确保 `try_files $uri $uri/ /index.html;` 配置正确
|
||||
|
||||
### Q2: API 请求跨域
|
||||
|
||||
**原因**: 前端和后端域名不同
|
||||
|
||||
**解决**: 在后端添加 CORS 头,或使用 OpenResty 代理统一域名
|
||||
|
||||
### Q3: 飞书回调失败
|
||||
|
||||
**原因**: 回调地址配置错误或 SSL 证书问题
|
||||
|
||||
**解决**:
|
||||
- 确认飞书后台配置的回调地址为 `https://xsm.hnxinyouhe.com/login/callback`
|
||||
- 确保服务器可公网访问
|
||||
- 检查 SSL 证书是否有效
|
||||
|
||||
### Q4: 容器无法连接数据库
|
||||
|
||||
**原因**: 容器网络不在同一个网络
|
||||
|
||||
**解决**: 确保后端容器和 MySQL/Redis 容器在同一个 Docker 网络(如 1panel-network)
|
||||
|
||||
---
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题,请联系开发团队。
|
||||
Reference in New Issue
Block a user