mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
DevOps: Add PM2 deployment scripts
Add complete PM2 deployment solution: - pm2.config.js: Dynamic path configuration - pm2.sh: One-click management script - PM2_DEPLOYMENT.md: Deployment guide Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
300
PM2_DEPLOYMENT.md
Normal file
300
PM2_DEPLOYMENT.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# NoFX Trading Bot - PM2 部署指南
|
||||
|
||||
使用 PM2 进行本地开发和生产部署的完整指南。
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 安装 PM2
|
||||
|
||||
```bash
|
||||
npm install -g pm2
|
||||
```
|
||||
|
||||
### 2. 一键启动
|
||||
|
||||
```bash
|
||||
./pm2.sh start
|
||||
```
|
||||
|
||||
就这么简单!前后端将自动启动。
|
||||
|
||||
---
|
||||
|
||||
## 📋 所有命令
|
||||
|
||||
### 服务管理
|
||||
|
||||
```bash
|
||||
# 启动服务
|
||||
./pm2.sh start
|
||||
|
||||
# 停止服务
|
||||
./pm2.sh stop
|
||||
|
||||
# 重启服务
|
||||
./pm2.sh restart
|
||||
|
||||
# 查看状态
|
||||
./pm2.sh status
|
||||
|
||||
# 删除服务
|
||||
./pm2.sh delete
|
||||
```
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# 查看所有日志(实时)
|
||||
./pm2.sh logs
|
||||
|
||||
# 只看后端日志
|
||||
./pm2.sh logs backend
|
||||
|
||||
# 只看前端日志
|
||||
./pm2.sh logs frontend
|
||||
```
|
||||
|
||||
### 构建与编译
|
||||
|
||||
```bash
|
||||
# 编译后端
|
||||
./pm2.sh build
|
||||
|
||||
# 重新编译后端并重启
|
||||
./pm2.sh rebuild
|
||||
```
|
||||
|
||||
### 监控
|
||||
|
||||
```bash
|
||||
# 打开 PM2 监控面板(实时CPU/内存)
|
||||
./pm2.sh monitor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 访问地址
|
||||
|
||||
启动成功后:
|
||||
|
||||
- **前端 Web 界面**: http://localhost:3000
|
||||
- **后端 API**: http://localhost:8080
|
||||
- **健康检查**: http://localhost:8080/health
|
||||
|
||||
---
|
||||
|
||||
## 🔧 配置文件
|
||||
|
||||
### pm2.config.js
|
||||
|
||||
PM2 配置文件,定义了前后端的启动参数:
|
||||
|
||||
```javascript
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'nofx-backend',
|
||||
script: './nofx', // Go 二进制文件
|
||||
cwd: __dirname, // 动态获取当前目录
|
||||
autorestart: true,
|
||||
max_memory_restart: '500M'
|
||||
},
|
||||
{
|
||||
name: 'nofx-frontend',
|
||||
script: 'npm',
|
||||
args: 'run dev', // Vite 开发服务器
|
||||
cwd: path.join(__dirname, 'web'), // 动态拼接路径
|
||||
autorestart: true,
|
||||
max_memory_restart: '300M'
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
**修改配置后需要重启:**
|
||||
```bash
|
||||
./pm2.sh restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 日志文件位置
|
||||
|
||||
- **后端日志**: `./logs/backend-error.log` 和 `./logs/backend-out.log`
|
||||
- **前端日志**: `./web/logs/frontend-error.log` 和 `./web/logs/frontend-out.log`
|
||||
|
||||
---
|
||||
|
||||
## 🔄 开机自启动
|
||||
|
||||
设置 PM2 开机自启动:
|
||||
|
||||
```bash
|
||||
# 1. 启动服务
|
||||
./pm2.sh start
|
||||
|
||||
# 2. 保存当前进程列表
|
||||
pm2 save
|
||||
|
||||
# 3. 生成启动脚本
|
||||
pm2 startup
|
||||
|
||||
# 4. 按照提示执行命令(需要 sudo)
|
||||
```
|
||||
|
||||
**取消开机自启动:**
|
||||
```bash
|
||||
pm2 unstartup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 常见操作
|
||||
|
||||
### 修改代码后重启
|
||||
|
||||
**后端修改:**
|
||||
```bash
|
||||
./pm2.sh rebuild # 自动编译并重启
|
||||
```
|
||||
|
||||
**前端修改:**
|
||||
```bash
|
||||
./pm2.sh restart # Vite 会自动热重载,无需重启
|
||||
```
|
||||
|
||||
### 查看实时资源占用
|
||||
|
||||
```bash
|
||||
./pm2.sh monitor
|
||||
```
|
||||
|
||||
### 查看详细信息
|
||||
|
||||
```bash
|
||||
pm2 info nofx-backend # 后端详情
|
||||
pm2 info nofx-frontend # 前端详情
|
||||
```
|
||||
|
||||
### 清空日志
|
||||
|
||||
```bash
|
||||
pm2 flush
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 故障排查
|
||||
|
||||
### 服务启动失败
|
||||
|
||||
```bash
|
||||
# 1. 查看详细错误
|
||||
./pm2.sh logs
|
||||
|
||||
# 2. 检查端口占用
|
||||
lsof -i :8080 # 后端端口
|
||||
lsof -i :3000 # 前端端口
|
||||
|
||||
# 3. 手动编译测试
|
||||
go build -o nofx
|
||||
./nofx
|
||||
```
|
||||
|
||||
### 后端无法启动
|
||||
|
||||
```bash
|
||||
# 检查 config.json 是否存在
|
||||
ls -l config.json
|
||||
|
||||
# 检查权限
|
||||
chmod +x nofx
|
||||
|
||||
# 手动运行看报错
|
||||
./nofx
|
||||
```
|
||||
|
||||
### 前端无法访问
|
||||
|
||||
```bash
|
||||
# 检查 node_modules
|
||||
cd web && npm install
|
||||
|
||||
# 手动启动测试
|
||||
npm run dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 生产环境建议
|
||||
|
||||
### 1. 使用生产模式
|
||||
|
||||
修改 `pm2.config.js`:
|
||||
|
||||
```javascript
|
||||
{
|
||||
name: 'nofx-frontend',
|
||||
script: 'npm',
|
||||
args: 'run preview', // 改为 preview(需先 npm run build)
|
||||
env: {
|
||||
NODE_ENV: 'production'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 增加实例数(负载均衡)
|
||||
|
||||
```javascript
|
||||
{
|
||||
name: 'nofx-backend',
|
||||
script: './nofx',
|
||||
instances: 2, // 启动 2 个实例
|
||||
exec_mode: 'cluster'
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 自动重启策略
|
||||
|
||||
```javascript
|
||||
{
|
||||
autorestart: true,
|
||||
max_restarts: 10,
|
||||
min_uptime: '10s',
|
||||
max_memory_restart: '500M'
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 与 Docker 部署的对比
|
||||
|
||||
| 特性 | PM2 部署 | Docker 部署 |
|
||||
|------|---------|------------|
|
||||
| 启动速度 | ⚡ 快 | 🐌 较慢 |
|
||||
| 资源占用 | 💚 低 | 🟡 中等 |
|
||||
| 隔离性 | 🟡 中等 | 💚 高 |
|
||||
| 适用场景 | 开发/单机 | 生产/集群 |
|
||||
| 配置复杂度 | 💚 简单 | 🟡 中等 |
|
||||
|
||||
**建议:**
|
||||
- **开发环境**: 使用 `./pm2.sh`
|
||||
- **生产环境**: 使用 `./start.sh` (Docker)
|
||||
|
||||
---
|
||||
|
||||
## 🆘 获取帮助
|
||||
|
||||
```bash
|
||||
./pm2.sh help
|
||||
```
|
||||
|
||||
或查看 PM2 官方文档:https://pm2.keymetrics.io/
|
||||
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
|
||||
MIT
|
||||
41
pm2.config.js
Normal file
41
pm2.config.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'nofx-backend',
|
||||
script: './nofx',
|
||||
cwd: __dirname, // 使用当前目录(配置文件所在目录)
|
||||
interpreter: 'none', // 不使用解释器,直接执行二进制文件
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '500M',
|
||||
env: {
|
||||
NODE_ENV: 'production'
|
||||
},
|
||||
error_file: './logs/backend-error.log',
|
||||
out_file: './logs/backend-out.log',
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true
|
||||
},
|
||||
{
|
||||
name: 'nofx-frontend',
|
||||
script: 'npm',
|
||||
args: 'run dev',
|
||||
cwd: path.join(__dirname, 'web'), // 动态拼接 web 目录
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '300M',
|
||||
env: {
|
||||
NODE_ENV: 'development',
|
||||
PORT: 3000
|
||||
},
|
||||
error_file: './logs/frontend-error.log',
|
||||
out_file: './logs/frontend-out.log',
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true
|
||||
}
|
||||
]
|
||||
};
|
||||
258
pm2.sh
Executable file
258
pm2.sh
Executable file
@@ -0,0 +1,258 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NoFX Trading Bot - PM2 管理脚本
|
||||
# 用法: ./pm2.sh [start|stop|restart|status|logs|build]
|
||||
|
||||
set -e
|
||||
|
||||
# 自动获取脚本所在目录(支持符号链接)
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 函数:打印带颜色的消息
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo -e "${PURPLE}═══════════════════════════════════════${NC}"
|
||||
echo -e "${PURPLE} 🤖 NoFX Trading Bot - PM2 Manager${NC}"
|
||||
echo -e "${PURPLE}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 函数:检查 PM2 是否安装
|
||||
check_pm2() {
|
||||
if ! command -v pm2 &> /dev/null; then
|
||||
print_error "PM2 未安装,请先安装: npm install -g pm2"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:确保日志目录存在
|
||||
ensure_log_dirs() {
|
||||
mkdir -p "$PROJECT_ROOT/logs"
|
||||
mkdir -p "$PROJECT_ROOT/web/logs"
|
||||
print_info "日志目录已创建"
|
||||
}
|
||||
|
||||
# 函数:编译后端
|
||||
build_backend() {
|
||||
print_info "正在编译后端..."
|
||||
go build -o nofx
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "后端编译完成"
|
||||
else
|
||||
print_error "后端编译失败"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:构建前端(生产环境)
|
||||
build_frontend() {
|
||||
print_info "正在构建前端..."
|
||||
cd web
|
||||
npm run build
|
||||
if [ $? -eq 0 ]; then
|
||||
print_success "前端构建完成"
|
||||
cd ..
|
||||
else
|
||||
print_error "前端构建失败"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:启动服务
|
||||
start_services() {
|
||||
print_header
|
||||
ensure_log_dirs
|
||||
|
||||
# 检查后端二进制文件是否存在
|
||||
if [ ! -f "./nofx" ]; then
|
||||
print_warning "后端二进制文件不存在,开始编译..."
|
||||
build_backend
|
||||
fi
|
||||
|
||||
print_info "正在启动服务..."
|
||||
pm2 start pm2.config.js
|
||||
|
||||
sleep 2
|
||||
pm2 status
|
||||
|
||||
echo ""
|
||||
print_success "服务启动完成!"
|
||||
echo ""
|
||||
echo -e "${CYAN}📊 访问地址:${NC}"
|
||||
echo -e " ${GREEN}前端:${NC} http://localhost:3000"
|
||||
echo -e " ${GREEN}后端 API:${NC} http://localhost:8080"
|
||||
echo ""
|
||||
echo -e "${CYAN}📝 查看日志:${NC}"
|
||||
echo -e " ${GREEN}实时日志:${NC} ./pm2.sh logs"
|
||||
echo -e " ${GREEN}后端日志:${NC} ./pm2.sh logs backend"
|
||||
echo -e " ${GREEN}前端日志:${NC} ./pm2.sh logs frontend"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 函数:停止服务
|
||||
stop_services() {
|
||||
print_header
|
||||
print_info "正在停止服务..."
|
||||
pm2 stop pm2.config.js
|
||||
print_success "服务已停止"
|
||||
}
|
||||
|
||||
# 函数:重启服务
|
||||
restart_services() {
|
||||
print_header
|
||||
print_info "正在重启服务..."
|
||||
pm2 restart pm2.config.js
|
||||
sleep 2
|
||||
pm2 status
|
||||
print_success "服务已重启"
|
||||
}
|
||||
|
||||
# 函数:删除服务
|
||||
delete_services() {
|
||||
print_header
|
||||
print_warning "正在删除 PM2 服务..."
|
||||
pm2 delete pm2.config.js || true
|
||||
print_success "PM2 服务已删除"
|
||||
}
|
||||
|
||||
# 函数:查看状态
|
||||
show_status() {
|
||||
print_header
|
||||
pm2 status
|
||||
echo ""
|
||||
print_info "详细信息:"
|
||||
pm2 info nofx-backend
|
||||
echo ""
|
||||
pm2 info nofx-frontend
|
||||
}
|
||||
|
||||
# 函数:查看日志
|
||||
show_logs() {
|
||||
if [ -z "$2" ]; then
|
||||
# 显示所有日志
|
||||
pm2 logs
|
||||
elif [ "$2" = "backend" ]; then
|
||||
pm2 logs nofx-backend
|
||||
elif [ "$2" = "frontend" ]; then
|
||||
pm2 logs nofx-frontend
|
||||
else
|
||||
print_error "未知的日志类型: $2"
|
||||
print_info "用法: ./pm2.sh logs [backend|frontend]"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:监控
|
||||
show_monitor() {
|
||||
print_header
|
||||
print_info "启动 PM2 监控面板..."
|
||||
pm2 monit
|
||||
}
|
||||
|
||||
# 函数:重新编译并重启
|
||||
rebuild_and_restart() {
|
||||
print_header
|
||||
print_info "正在重新编译后端..."
|
||||
build_backend
|
||||
|
||||
print_info "正在重启后端服务..."
|
||||
pm2 restart nofx-backend
|
||||
|
||||
sleep 2
|
||||
pm2 status
|
||||
print_success "后端已重新编译并重启"
|
||||
}
|
||||
|
||||
# 函数:显示帮助
|
||||
show_help() {
|
||||
print_header
|
||||
echo -e "${CYAN}使用方法:${NC}"
|
||||
echo " ./pm2.sh [command]"
|
||||
echo ""
|
||||
echo -e "${CYAN}可用命令:${NC}"
|
||||
echo -e " ${GREEN}start${NC} - 启动前后端服务"
|
||||
echo -e " ${GREEN}stop${NC} - 停止所有服务"
|
||||
echo -e " ${GREEN}restart${NC} - 重启所有服务"
|
||||
echo -e " ${GREEN}status${NC} - 查看服务状态"
|
||||
echo -e " ${GREEN}logs${NC} - 查看所有日志 (Ctrl+C 退出)"
|
||||
echo -e " ${GREEN}logs backend${NC} - 查看后端日志"
|
||||
echo -e " ${GREEN}logs frontend${NC} - 查看前端日志"
|
||||
echo -e " ${GREEN}monitor${NC} - 打开 PM2 监控面板"
|
||||
echo -e " ${GREEN}build${NC} - 编译后端"
|
||||
echo -e " ${GREEN}rebuild${NC} - 重新编译后端并重启"
|
||||
echo -e " ${GREEN}delete${NC} - 删除 PM2 服务"
|
||||
echo -e " ${GREEN}help${NC} - 显示此帮助信息"
|
||||
echo ""
|
||||
echo -e "${CYAN}示例:${NC}"
|
||||
echo " ./pm2.sh start # 启动服务"
|
||||
echo " ./pm2.sh logs backend # 查看后端日志"
|
||||
echo " ./pm2.sh rebuild # 重新编译后端并重启"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 主逻辑
|
||||
check_pm2
|
||||
|
||||
case "${1:-help}" in
|
||||
start)
|
||||
start_services
|
||||
;;
|
||||
stop)
|
||||
stop_services
|
||||
;;
|
||||
restart)
|
||||
restart_services
|
||||
;;
|
||||
status)
|
||||
show_status
|
||||
;;
|
||||
logs)
|
||||
show_logs "$@"
|
||||
;;
|
||||
monitor|mon)
|
||||
show_monitor
|
||||
;;
|
||||
build)
|
||||
build_backend
|
||||
;;
|
||||
rebuild)
|
||||
rebuild_and_restart
|
||||
;;
|
||||
delete|remove)
|
||||
delete_services
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
print_error "未知命令: $1"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user