# Ubuntu 后台运行(中控 + 子代理) 各 `crypto_monitor_*` 策略目录:首次 **`cp .env.example .env`** 并编辑;**`.env` 不进 Git**,`git pull` 不覆盖。升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`。子代理启动前须 **`source` 该目录 `.env`**(见下文)。 前台跑 `python agent.py` / `python hub.py` 时,关掉终端进程会结束。要**常驻后台**,可用下面三种之一(推荐 **systemd**)。 --- ## 一、tmux / screen(最简单,适合先试用) 仓库已提供 **一键起 3 个 agent(不含 OKX)** 的 screen 脚本(需可执行权限): ```bash chmod +x manual_trading_hub/scripts/start_agents_3screen.sh chmod +x manual_trading_hub/scripts/start_hub_screen.sh chmod +x manual_trading_hub/scripts/stop_agents_3screen.sh chmod +x manual_trading_hub/scripts/stop_hub_screen.sh ./manual_trading_hub/scripts/start_agents_3screen.sh ./manual_trading_hub/scripts/start_hub_screen.sh # 关闭: ./manual_trading_hub/scripts/stop_hub_screen.sh ./manual_trading_hub/scripts/stop_agents_3screen.sh ``` 脚本默认认为:`manual_trading_hub` 的**上一级目录**里并列放着三个 `crypto_monitor_*`。若你把 hub 单独放在 `/opt/crypto_monitor/manual_trading_hub`,而策略项目在例如 `/opt/crypto_monitor/` 下的其他位置,请先执行 `export MANUAL_TRADING_REPO_ROOT=/opt/crypto_monitor` 再运行 `start_agents_3screen.sh`。 启动后若 `screen -ls` 里没有 `mt-agent-*`,看日志:`tail -80 /opt/crypto_monitor/manual_trading_hub/logs/mt-agent-bn.log`。 ### 局域网内其他电脑访问中控 中控 **默认** `HUB_HOST=0.0.0.0`、`HUB_TRUST_LAN=开启`,同一局域网内可用 `http://<中控机局域网IP>:5100/` 打开页面(本机仍可用 `http://127.0.0.1:5100/`)。请确保防火墙放行端口,例如:`sudo ufw allow 5100/tcp`。 若改为 **仅本机** 访问:`HUB_HOST=127.0.0.1` 或 `HUB_TRUST_LAN=0`,重启 hub。 也可把上述变量写进 `manual_trading_hub/.env`,再用 `start_hub_screen.sh` 启动。 以下为手工 tmux 示例: ```bash # 新建会话,在里面照常启动 agent 或 hub,然后按键 Ctrl+B 再按 D 脱离 tmux new -s hub cd /opt/crypto_monitor/manual_trading_hub && source .venv/bin/activate && python hub.py # Ctrl+B, D tmux new -s agent-bn cd /opt/crypto_monitor/crypto_monitor_binance && set -a && source .env && set +a export EXCHANGE=binance PORT=15200 HOST=127.0.0.1 source /opt/crypto_monitor/manual_trading_hub/.venv/bin/activate python /opt/crypto_monitor/manual_trading_hub/agent.py # Ctrl+B, D ``` 重新连上:`tmux attach -t hub` --- ## 二、nohup(快速、无守护重启) ```bash cd /opt/crypto_monitor/manual_trading_hub source .venv/bin/activate nohup python hub.py > /tmp/manual-hub.log 2>&1 & ``` 子代理同理(每个账户一条):**先 `source` 该策略目录的 `.env`**(`agent.py` 不会自己读文件),再 `nohup python …/agent.py`。 停进程:`ps aux | grep hub.py` 或 `grep agent.py`,再 `kill `。 --- ## 三、systemd(推荐:开机自启、崩溃自动拉起) 1. 把下面两个示例里的 **`YOUR_REPO`** 改成 **`/opt/crypto_monitor`**(或你本机实际仓库根目录),`YOUR_USER` 改成 Linux 用户名。 2. 复制到 `/etc/systemd/system/`(需 sudo),文件名例如 `manual-hub.service`、`manual-agent-binance.service`。 3. 执行: ```bash sudo systemctl daemon-reload sudo systemctl enable --now manual-hub.service sudo systemctl enable --now manual-agent-binance.service # 其余 OKX / Gate 同理再建 3 个 unit 或合并为多条 ``` 查看状态:`sudo systemctl status manual-hub` 日志:`journalctl -u manual-hub -f` ### 示例:`/etc/systemd/system/manual-hub.service` ```ini [Unit] Description=手工交易中控 hub After=network-online.target Wants=network-online.target [Service] Type=simple User=YOUR_USER WorkingDirectory=YOUR_REPO/manual_trading_hub Environment=HUB_HOST=0.0.0.0 Environment=HUB_TRUST_LAN=1 Environment=HUB_PORT=5100 ExecStart=YOUR_REPO/manual_trading_hub/.venv/bin/python YOUR_REPO/manual_trading_hub/hub.py Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` **注意:** `agent.py` **不会**像 Flask 那样自动加载目录里的 `.env`,密钥必须由 **systemd 的 `EnvironmentFile=`** 注入,或用下面 `bash -c` 方式 `source .env` 后再启动。 ### 示例:`/etc/systemd/system/manual-agent-binance.service` ```ini [Unit] Description=手工交易子代理 Binance After=network-online.target Wants=network-online.target [Service] Type=simple User=YOUR_USER WorkingDirectory=YOUR_REPO/crypto_monitor_binance Environment=PATH=YOUR_REPO/manual_trading_hub/.venv/bin:/usr/bin:/bin Environment=EXCHANGE=binance Environment=PORT=15200 Environment=HOST=127.0.0.1 # 把该账户的 .env 注入进程(与 Flask 同一份即可;仅支持 KEY=VALUE 行,勿写 shell 语法) EnvironmentFile=-YOUR_REPO/crypto_monitor_binance/.env ExecStart=YOUR_REPO/manual_trading_hub/.venv/bin/python YOUR_REPO/manual_trading_hub/agent.py Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` 若 `.env` 含 **systemd 无法解析** 的内容(复杂引号、`export` 等),改用: ```ini ExecStart=/bin/bash -lc 'set -a; source YOUR_REPO/crypto_monitor_binance/.env; set +a; exec YOUR_REPO/manual_trading_hub/.venv/bin/python YOUR_REPO/manual_trading_hub/agent.py' ``` 并删掉或注释掉 `EnvironmentFile=` 行,避免重复注入。 **OKX / Gate / Gate-Bot**:各复制一份 `.service`,改 `Description`、`WorkingDirectory`、以及 `EXCHANGE` / `PORT`(`15201`、`15202`、`15203`)。 --- ## 四、常见问题(子代理 / screen / 依赖) 1. **`curl http://127.0.0.1:15202/status`(或其它端口)返回 `ok:false`,错误里提到 pysocks / SOCKS** 策略目录 `.env` 里配置了 `GATE_SOCKS_PROXY`(或 `BINANCE_SOCKS_PROXY`、`OKX_SOCKS_PROXY`)时,ccxt 需要 **PySocks**。在 **`/opt/crypto_monitor/manual_trading_hub/.venv`**(或你本机的 `manual_trading_hub/.venv`)中执行: `pip install PySocks` 或 `pip install -r requirements.txt`。 2. **已经 `pip install PySocks`,错误文案完全不变** 子代理是**常驻进程**,首次请求已创建 ccxt;在运行中的进程里**仅安装包不会自动生效**。须**重启**该 agent:例如 `screen -S mt-agent-gate -X quit` 再执行 `start_agents_3screen.sh`(或你的等价启动方式)。**不要**依赖「会话还在、以为已经更新」的旧进程。 3. **`start_agents_3screen.sh` 打印「已存在会话、跳过」** 脚本检测到 `mt-agent-*` 已在跑会跳过创建。需要先停再启: `./stop_agents_3screen.sh` 或对单个会话:`screen -S mt-agent-gate -X quit`,再跑启动脚本。 4. **确认 15200/15202/15203 上的进程用的是 hub 的 venv** ```bash ps aux | grep agent.py tr '\0' ' ' < /proc//cmdline; echo ``` 应看到 `…/manual_trading_hub/.venv/bin/python` 与 `…/manual_trading_hub/agent.py`。若用的是系统 `python3`,要么在**同一解释器环境**里装依赖,要么改为用 `start_agents_3screen.sh` 启动(脚本内写死 `VENV_PY`)。 5. **中控某账户一直红 / 非 JSON** 对应该端口的 agent 未启动,或 `HUB_AGENTS` 与 agent 的 `PORT` 不一致。本机先测: `curl -sS http://127.0.0.1:1520x/status | head -c 400` 再看 `logs/mt-agent-*.log`。 6. **子代理端口与 Flask 冲突** agent 使用环境变量 **`PORT`**(脚本里 15200、15202、15203);各策略 `.env` 里的 **`APP_PORT`** 给 Flask。二者**不能**相同。 7. **systemd 下改依赖或 `.env` 后** 与 screen 相同:`pip install` 或改 `EnvironmentFile` 后需 **`systemctl restart `**,否则仍是旧进程。 --- ## 五、注意 - 子代理与中控仍建议只监听 **127.0.0.1**;Flask 的 `APP_HOST=0.0.0.0` 与中控无关。 - 若策略项目用**自己的** `.venv`,把 `ExecStart` 里的 Python 改成该 venv 的 `python`,但 `agent.py` 路径仍指向 `manual_trading_hub/agent.py`。 同目录下另有 `example-systemd/*.service.example` 可复制后改路径使用。