Files
crypto_monitor/manual_trading_hub/部署文档.md
T
2026-05-25 11:49:53 +08:00

335 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多账户交易中控 — 部署文档(含 PM2)
本文档说明在 **Ubuntu / Linux** 上部署 **manual_trading_hub**(复盘系统中控:监控区、系统设置、登录保护)的推荐步骤。
- 功能与界面:[使用说明.md](./使用说明.md)
- **局域网 IP:端口 / 反代域名、中控打开实例免登录**:[局域网与反代部署说明.md](./局域网与反代部署说明.md)
- 故障实录:[常见问题.md](./常见问题.md)
- 环境变量模板:[.env.example](./.env.example)
---
## 一、部署目标
| 组件 | 作用 | 默认监听 |
|------|------|----------|
| **hub.py** | 中控 Web + API | `0.0.0.0:5100` |
| **agent.py × N** | 各账户持仓 / 紧急全平 | `127.0.0.1:15200``15203` |
| **crypto_monitor_*.app** | 策略、关键位、下单逻辑 | 各目录 `.env``APP_PORT` |
- 账户列表与 URL 由 **`hub_settings.json`**(网页「系统设置」保存)或内置默认维护;**不再使用** `HUB_AGENTS`
- 四实例 Flask **无需为中控改业务代码**(已注册 `hub_bridge`);与中控并行运行。
---
## 二、前置条件
1. **Python 3.10+**`python3-venv``pip`
2. **Node.js + npm**(用于安装 PM2):`sudo npm i -g pm2`
3.`crypto_monitor_*` 目录已 **`cp .env.example .env`** 并填好 API 密钥。
4. 端口无冲突:`5100``15200``15203`、各实例 `APP_PORT`5000/5001/5002/5004)。
5. 建议代码路径:`/opt/crypto_monitor/`(下文用此示例,请按实际路径替换)。
---
## 三、安装中控依赖
```bash
cd /opt/crypto_monitor/manual_trading_hub
python3 -m venv .venv
source .venv/bin/activate # 激活 venv(当前终端后续 pip/python 走虚拟环境)
pip install -r requirements.txt
cp .env.example .env
# 编辑 .envHUB_PORT、HUB_DISABLED_IDS、公网时 HUB_BRIDGE_TOKEN 等
chmod +x scripts/run_hub.sh scripts/run_agent.sh scripts/pm2_hub.sh scripts/pm2_agents.sh
chmod +x scripts/fix_hub_deps.sh scripts/verify_hub_deploy.sh scripts/fix_env_crlf.sh
deactivate # 可选;交给 PM2 时不必保持激活
```
**依赖说明**`requirements.txt`**`python-multipart`**(FastAPI 表单解析;旧版若保留下单接口时需要)。当前中控**已移除下单区**,但仍建议安装完整依赖。
说明:
- **安装依赖**`source .venv/bin/activate` 后用 `pip install` 即可;不写 `activate` 时也可用 **`.venv/bin/pip install -r requirements.txt`**(效果相同)。
- **PM2 启动**:由 `scripts/run_hub.sh` 固定调用 **`.venv/bin/python`****不依赖**你是否在 shell 里激活过 venv。
子代理也使用 **本目录 `.venv`** 里的 Python(与各策略 Flask 的 venv 可分开)。
---
## 四、推荐启动顺序
```
1. 各实例 FlaskAPP_PORT ← 各 crypto_monitor_* 目录 ecosystem.config.cjs
2. 中控 + 子代理(5100 + 1520015203 ← 本目录一条 PM2 命令同时启动
```
**`ecosystem.config.cjs` 会一次拉起 4 个 agent + 1 个 hub**,无需再单独 `pm2 start` 子代理。
仅反代中控到公网时:Flask / agent 仍只监听 **127.0.0.1**;系统设置里 URL 填 `http://127.0.0.1:端口`
---
## 五、PM2 托管(hub + agent 一起启动,推荐)
### 5.1 一条命令启动全部
| 文件 | 包含进程 |
|------|----------|
| `ecosystem.config.cjs` | `manual-agent-binance` / `okx` / `gate` / `gate-bot` + **`manual-trading-hub`** |
`run_hub.sh` 加载 **`manual_trading_hub/.env`** 后执行 `hub.py`;各 agent 经 **`run_agent.sh`** 在对应策略目录加载 **`.env`**(含 API 密钥),再执行 `agent.py`
```bash
cd /opt/crypto_monitor/manual_trading_hub
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
pm2 start ecosystem.config.cjs # 5 个进程一起起
pm2 save
# 或
bash scripts/pm2_hub.sh start
```
### 5.2 PM2 进程一览
| 进程名 | 工作目录 | 端口/说明 |
|--------|----------|-----------|
| manual-agent-binance | crypto_monitor_binance | agent `15200` |
| manual-agent-okx | crypto_monitor_okx | agent `15201` |
| manual-agent-gate | crypto_monitor_gate | agent `15202` |
| manual-agent-gate-bot | crypto_monitor_gate_bot | agent `15203` |
| manual-trading-hub | manual_trading_hub | hub `5100` |
OKX 子代理会启动,但中控默认 `HUB_DISABLED_IDS=1` 不参与监控;不用 OKX 可 `pm2 stop manual-agent-okx`
### 5.3 常用运维命令
```bash
pm2 status
pm2 logs manual-trading-hub --lines 200
pm2 restart ecosystem.config.cjs # 重启 hub + 全部 agent
bash scripts/pm2_hub.sh restart # 同上
bash scripts/pm2_hub.sh stop
bash scripts/pm2_hub.sh logs
```
仅重启中控、不动 agent
```bash
pm2 restart manual-trading-hub
```
仅重启子代理:
```bash
pm2 restart manual-agent-binance manual-agent-gate manual-agent-gate-bot
# 或
bash scripts/pm2_agents.sh restart
```
### 5.4 开机自启
```bash
pm2 save
pm2 startup
# 按终端提示执行一行 sudo 命令后,再 pm2 save
```
### 5.5 与各实例 Flask 一起查看
```bash
pm2 status
# 示例同时存在:
# manual-trading-hub、manual-agent-*
# crypto_binance / crypto_gate …(各策略目录自有 ecosystem.config.cjs
```
### 5.6 Gate 子代理「一会能连、一会子代理不可用」(Windows `.env` 换行)
**现象**:仅 Gate 训练 / Gate 趋势卡片红字「子代理不可用」;`pm2 logs manual-agent-gate` 反复出现:
```text
./.env: line 22: $'\r': command not found
agent start: exchange=gate port=15202 ...
```
**原因**:在 Windows 编辑的 `crypto_monitor_gate/.env``crypto_monitor_gate_bot/.env`**CRLF**Linux 上 `source` 失败;PM2 反复重启,中控轮询时偶发连不上(**不是外网问题**)。
**处理**(在服务器仓库根执行):
```bash
cd /opt/crypto_monitor
sed -i 's/\r$//' crypto_monitor_gate/.env crypto_monitor_gate_bot/.env
bash manual_trading_hub/scripts/fix_env_crlf.sh
cd manual_trading_hub
pm2 delete manual-agent-gate manual-agent-gate-bot 2>/dev/null || true
pm2 start ecosystem.config.cjs --only manual-agent-gate
pm2 start ecosystem.config.cjs --only manual-agent-gate-bot
pm2 save
curl -s http://127.0.0.1:15202/status | head -c 200 # 应 ok:true
```
**预防**`.env` 保存为 **LF**Windows 用 `deploy/setup_env.ps1` 复制 `.env.example` 时已写 LF。子代理须经 **`scripts/run_agent.sh`** 启动(内置去 CRLF 的 `load_dotenv_file`),勿裸跑 `python agent.py`
详见 [常见问题.md](./常见问题.md) **§3.1**、**§3.3**。
---
## 六、手动启动(不用 PM2 时)
需**分别**起 agent 与 hub(与 PM2 合并启动不同):
```bash
# 子代理:scripts/start_agents_3screen.sh 或每目录手动 agent.py
# 中控:
cd /opt/crypto_monitor/manual_trading_hub
bash scripts/run_hub.sh
```
---
## 七、浏览器验收
1. **http://127.0.0.1:5100/login** — 若 `.env` 已设 `HUB_PASSWORD`,用 `HUB_USERNAME` / `HUB_PASSWORD` 登录。
2. **http://127.0.0.1:5100/monitor** — 已启用账户显示持仓;Flask 已起时有关键位/趋势信息。
3. **http://127.0.0.1:5100/settings** — 保存后生成 `hub_settings.json`(增加第五户、Gate 子账户等见 [使用说明.md §4.3](./使用说明.md#43-增加账户例如再挂一个-gate))。
4. 监控卡片 **「实例」** — 在各 `crypto_monitor_*` 网页做下单、关键位、趋势;中控**不提供**下单表单。
**命令行验收**(推荐):
```bash
cd /opt/crypto_monitor/manual_trading_hub
bash scripts/verify_hub_deploy.sh
```
应看到:`OK: 无 api_trade_key``HTTP 200`JSON 含 `"build":"20260521-no-trade-ui"`
```bash
curl -s http://127.0.0.1:5100/api/ping
curl -s http://127.0.0.1:15200/status | head -c 200
```
---
## 八、仅反代中控到公网(实例不反代)
1. Nginx/Caddy 反代到 **`127.0.0.1:5100`**,配置 **HTTPS**
2. 反代需传递(登录 Cookie 正确识别 HTTPS):
```nginx
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
```
3. `manual_trading_hub/.env` **务必设置**
```env
HUB_USERNAME=你的用户名
HUB_PASSWORD=你的强密码
HUB_SESSION_SECRET=随机长串
HUB_COOKIE_SECURE=true
```
4. `hub_settings.json` 中 Flask/Agent 保持 **`http://127.0.0.1:...`**(中控本机调 API)。
5. 四实例 **`APP_AUTH_DISABLED=false`** + 与中控相同 **`HUB_BRIDGE_TOKEN`**。
6. 子代理 **`HOST=127.0.0.1`**;防火墙勿对公网开放 `15200``15203`、各 `APP_PORT`。
7. **复盘/实例外链**`HUB_PUBLIC_ORIGIN=https://你的域名` 或内网 IP;否则其它设备点「复盘」会跳到 `127.0.0.1`。
**说明**HTTPS 域名与 HTTP `内网IP:5100` Cookie **不共用**;内网访问 IP 需在 IP 地址再登录一次(见 [常见问题.md](./常见问题.md) §2.1)。
---
## 九、环境变量(中控 `.env`
| 变量 | 默认 | 说明 |
|------|------|------|
| `HUB_HOST` | `0.0.0.0` | 监听地址 |
| `HUB_PORT` | `5100` | 端口 |
| `HUB_DISABLED_IDS` | `1` | 强制关闭的账户 id(OKX) |
| `HUB_TRUST_LAN` | `true` | 私网可访问;仅本机可 `false` |
| `HUB_PUBLIC_ORIGIN` | 空 | 浏览器用复盘链接;如 `http://192.168.1.100`(**内网其它电脑访问中控时建议设置**) |
| `HUB_BRIDGE_TOKEN` | 空 | 与四实例一致;公网建议配置 |
| `HUB_USERNAME` | `admin` | Web 登录用户名 |
| `HUB_PASSWORD` | 空 | 非空即启用登录 |
| `HUB_SESSION_SECRET` | — | 会话签名 |
| `HUB_COOKIE_SECURE` | `false` | HTTPS 反代建议 `true` |
| `HUB_SESSION_DAYS` | `7` | 登录保持天数 |
本地联调、实例 `APP_AUTH_DISABLED=true` 时可不配 `HUB_BRIDGE_TOKEN`;本机不设 `HUB_PASSWORD` 则无需登录页。
---
## 十、升级与回滚
```bash
cd /opt/crypto_monitor
git pull
cd manual_trading_hub
bash scripts/fix_hub_deps.sh
bash scripts/verify_hub_deploy.sh
pm2 restart ecosystem.config.cjs
# 若只改了中控:pm2 restart manual-trading-hub
```
- **`hub_settings.json`**、**`.env`** 不在 Git 中,`git pull` 不会覆盖。
- 升级前可备份:`cp hub_settings.json hub_settings.json.bak`、`cp .env .env.bak`。
**升级后自检**`curl -s http://127.0.0.1:5100/api/ping` 须含 `"trade_ui":false`。若仍见 `api_trade_key` 报错,说明代码未更新或未重启,见 [常见问题.md](./常见问题.md) §1。
---
## 十一、故障排查(速查)
**完整实录**见 **[常见问题.md](./常见问题.md)**。
| 现象 | 处理 |
|------|------|
| PM2 启动后立刻退出 | `pm2 logs manual-trading-hub`;检查 `.venv`、`.env`、`run_hub.sh` |
| `api_trade_key` / `python-multipart` | `git pull` → `bash scripts/fix_hub_deps.sh` → `verify_hub_deploy.sh` → 重启 hub |
| `verify` ping 解析失败 | hub 未起:`pm2 restart manual-trading-hub` |
| 余额显示 — | agent 未加载 `.env``fix_env_crlf.sh``run_agent.sh` |
| agent `$'\r': command not found` | `bash scripts/fix_env_crlf.sh` |
| 监控无持仓 | `curl http://127.0.0.1:15200/status` |
| 无关键位 / 401 | 启动 Flask;核对 `HUB_BRIDGE_TOKEN` / `hub_bridge` |
| 域名能登、IP 不能登 | 见常见问题 §2.1Cookie / HTTP vs HTTPS |
| 公网访问中控 403 | 反代到 `127.0.0.1:5100`,勿公网直连 5100 |
| 改 `.env` 不生效 | `pm2 restart manual-trading-hub` |
---
## 十二、其它常驻方式
- **screen**`scripts/start_hub_screen.sh` / `stop_hub_screen.sh`
- **systemd**`scripts/example-systemd/manual-hub.service.example`(复制并改路径)
与 PM2 **二选一** 即可,避免同一端口启动两份 hub。
---
## 十三、安全清单
- [ ] 公网仅暴露反代端口,不暴露 Flask/agent 端口
- [ ] 已设 `HUB_USERNAME` + `HUB_PASSWORD`(中控 Web 登录)
- [ ] HTTPS 反代已设 `HUB_COOKIE_SECURE=true` 且传递 `X-Forwarded-Proto`
- [ ] 公网已配置 `HUB_BRIDGE_TOKEN` + 实例关闭 `APP_AUTH_DISABLED`
- [ ] API Key 最小权限;交易所 IP 白名单
- [ ] 已告知操作人员「全局全平」不可撤销;中控**不在网页下单**
---
## 十四、文档索引
| 文档 | 内容 |
|------|------|
| [使用说明.md](./使用说明.md) | 功能、页面、API、环境变量 |
| [常见问题.md](./常见问题.md) | 故障实录 |
| [README.md](./README.md) | 速览 |
| [.env.example](./.env.example) | 环境变量模板 |
| [scripts/后台运行-Ubuntu.md](./scripts/后台运行-Ubuntu.md) | screen / systemd |
| `scripts/fix_hub_deps.sh` | 安装依赖 |
| `scripts/verify_hub_deploy.sh` | 部署验收 |
| `scripts/fix_env_crlf.sh` | 修复 .env 换行 |