ab9987e4c7
Co-authored-by: Cursor <cursoragent@cursor.com>
430 lines
13 KiB
Markdown
430 lines
13 KiB
Markdown
# 部署文档
|
||
|
||
国内期货交易监控复盘系统 — Ubuntu 服务器部署、更新与运维说明。
|
||
|
||
---
|
||
|
||
## 部署概要
|
||
|
||
| 项目 | 默认值 |
|
||
|------|--------|
|
||
| 部署目录 | `/opt/qihuo` |
|
||
| 运行用户 | `root`(与 `deploy.sh` / PM2 配置一致) |
|
||
| 服务端口 | `6600` |
|
||
| 进程管理 | PM2,应用名 `qihuo` |
|
||
| 数据库 | SQLite `futures.db` |
|
||
| 仓库 | https://git.bz121.com/dekun/qihuo.git |
|
||
|
||
---
|
||
|
||
## 环境要求
|
||
|
||
- **系统**:Ubuntu 20.04+(推荐)
|
||
- **Python**:3.10+(vnpy_ctp 要求 ≥3.10)
|
||
- **Node.js + PM2**:进程守护与开机自启
|
||
- **编译工具**(安装 vnpy_ctp 时需要):`build-essential`、`python3-dev`、`pkg-config`
|
||
- **网络**:
|
||
- `hq.sinajs.cn`(新浪行情)
|
||
- 企业微信 API(若启用推送)
|
||
- `git.bz121.com`(拉取代码)
|
||
- `pypi.org`(pip 安装依赖)
|
||
- SimNow / 期货公司 **CTP 前置地址**(下单与持仓,见下文)
|
||
|
||
---
|
||
|
||
## 一键部署(推荐)
|
||
|
||
以 **root** 登录服务器后执行:
|
||
|
||
```bash
|
||
cd /opt/qihuo
|
||
# 若目录不存在,先克隆:
|
||
# git clone https://git.bz121.com/dekun/qihuo.git /opt/qihuo
|
||
|
||
bash deploy.sh
|
||
```
|
||
|
||
`deploy.sh` 会自动完成:
|
||
|
||
1. 安装系统依赖:`python3`、`git`、`build-essential`、`python3-dev`、`pkg-config`、`locales`、`netcat-openbsd`、`pm2`
|
||
2. **时区**设为 `Asia/Shanghai`(与 SimNow 交易时段一致)
|
||
3. **locale**:生成 `zh_CN.GB18030`、`zh_CN.UTF-8`(CTP 登录必需,缺则进程崩溃)
|
||
4. `git pull` 或 `git clone` 到 `/opt/qihuo`
|
||
5. 创建/保留虚拟环境 `venv`,`pip install -r requirements.txt`,验证 `vnpy_ctp`
|
||
6. 首次生成 `.env`,并补全 `SIMNOW_ENV=实盘`、`CTP_AUTO_RECONNECT=true` 等缺项
|
||
7. **自动探测 SimNow 前置**(`nc` 测端口),写入可用的 `SIMNOW_TD/MD_ADDRESS`(优先 `182.254.243.31`,其次 `180.168.146.187`)
|
||
8. 若已配置 SimNow 账号,运行 `scripts/test_simnow.py` 验证连接
|
||
9. `pm2 restart --update-env` 或首次 `pm2 start`,并 `pm2 save`
|
||
|
||
部署完成后访问:`http://<服务器IP>:6600`
|
||
|
||
> 再次部署只需 `cd /opt/qihuo && bash deploy.sh`,无需手工装 locale 或改前置地址。
|
||
|
||
---
|
||
|
||
## 手动部署
|
||
|
||
### 1. 安装系统依赖
|
||
|
||
```bash
|
||
apt update
|
||
apt install -y python3 python3-venv python3-pip python3-dev pkg-config git nodejs npm build-essential locales netcat-openbsd
|
||
timedatectl set-timezone Asia/Shanghai
|
||
sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen
|
||
sed -i '/^# zh_CN.UTF-8/s/^# //' /etc/locale.gen
|
||
locale-gen zh_CN.GB18030 zh_CN.UTF-8
|
||
update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8
|
||
npm install -g pm2
|
||
```
|
||
|
||
`build-essential`、`python3-dev`、`pkg-config` 用于编译安装 **vnpy_ctp**(CTP 网关)。Meson 通过 pkg-config 查找 Python 头文件;缺 `pkg-config` 时会报 `Python dependency not found`。
|
||
|
||
### 2. 克隆代码
|
||
|
||
```bash
|
||
git clone https://git.bz121.com/dekun/qihuo.git /opt/qihuo
|
||
cd /opt/qihuo
|
||
```
|
||
|
||
### 3. Python 虚拟环境与依赖
|
||
|
||
```bash
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
pip install --upgrade pip
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
依赖已包含 **vnpy**、**vnpy_ctp**(CTP 报单)、**akshare**(手续费同步)。安装完成后可验证:
|
||
|
||
```bash
|
||
python -c "from vnpy_ctp import CtpGateway; print('vnpy_ctp OK')"
|
||
```
|
||
|
||
若提示找不到模块,查看本文「CTP / vnpy 故障排查」一节。
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
nano .env
|
||
```
|
||
|
||
| 变量 | 说明 |
|
||
|------|------|
|
||
| `HOST` | 监听地址,默认 `0.0.0.0` |
|
||
| `PORT` | 端口,默认 `6600` |
|
||
| `SECRET_KEY` | Flask Session 密钥,务必随机 |
|
||
| `ADMIN_USERNAME` | 初始管理员用户名 |
|
||
| `ADMIN_PASSWORD` | 初始管理员密码(仅首次建库生效) |
|
||
| `ADMIN_SYNC_FROM_ENV` | `true` 时重启可从 `.env` 同步账号密码 |
|
||
| `WECHAT_WEBHOOK` | 企业微信机器人地址(可选) |
|
||
| `QUOTE_SOURCE` | `sina`(默认)/ `ths` / `auto` |
|
||
| `THS_REFRESH_TOKEN` | 同花顺 iFinD token(机构用户) |
|
||
| `SIMNOW_USER` | SimNow 仿真账号(模拟盘必填) |
|
||
| `SIMNOW_PASSWORD` | SimNow 密码 |
|
||
| `SIMNOW_TD_ADDRESS` | SimNow 交易前置(以官网最新为准) |
|
||
| `SIMNOW_MD_ADDRESS` | SimNow 行情前置 |
|
||
| `CTP_LIVE_*` | 期货公司实盘 CTP(后期接入,见 `.env.example`) |
|
||
| `TRADING_MODE` | `simulation`(SimNow)/ `live`(实盘) |
|
||
|
||
示例:
|
||
|
||
```env
|
||
HOST=0.0.0.0
|
||
PORT=6600
|
||
SECRET_KEY=请替换为随机长字符串
|
||
ADMIN_USERNAME=admin
|
||
ADMIN_PASSWORD=你的强密码
|
||
ADMIN_SYNC_FROM_ENV=false
|
||
WECHAT_WEBHOOK=
|
||
QUOTE_SOURCE=sina
|
||
|
||
# —— SimNow 模拟盘(注册步骤见 docs/SIMNOW.md)——
|
||
SIMNOW_USER=你的SimNow账号
|
||
SIMNOW_PASSWORD=你的密码
|
||
SIMNOW_BROKER_ID=9999
|
||
SIMNOW_TD_ADDRESS=tcp://180.168.146.187:10201
|
||
SIMNOW_MD_ADDRESS=tcp://180.168.146.187:10211
|
||
SIMNOW_APP_ID=simnow_client_test
|
||
SIMNOW_AUTH_CODE=0000000000000000
|
||
SIMNOW_ENV=实盘
|
||
TRADING_MODE=simulation
|
||
```
|
||
|
||
SimNow 前置地址会随官网更新,部署前请到 [SimNow 官网](https://www.simnow.com.cn/) 核对 **7×24** 或交易时段地址。
|
||
|
||
### 6. PM2 启动
|
||
|
||
```bash
|
||
cd /opt/qihuo
|
||
pm2 start ecosystem.config.cjs
|
||
pm2 save
|
||
pm2 startup # 按提示执行命令,实现开机自启
|
||
```
|
||
|
||
### 7. 创建日志目录(若不存在)
|
||
|
||
```bash
|
||
mkdir -p /opt/qihuo/logs /opt/qihuo/uploads
|
||
```
|
||
|
||
---
|
||
|
||
## 更新部署
|
||
|
||
代码已推送后,在服务器执行:
|
||
|
||
```bash
|
||
cd /opt/qihuo
|
||
git fetch origin
|
||
git reset --hard origin/main
|
||
source venv/bin/activate
|
||
pip install -r requirements.txt
|
||
pm2 restart qihuo
|
||
```
|
||
|
||
若服务器曾用 SCP 覆盖文件导致 `git pull` 冲突,用 `git reset --hard origin/main` 与远端对齐。
|
||
|
||
若 `vnpy_ctp` 安装失败(常见于缺少编译环境):
|
||
|
||
```bash
|
||
apt install -y build-essential python3-dev pkg-config
|
||
source venv/bin/activate
|
||
pip install --no-cache-dir vnpy vnpy_ctp
|
||
pm2 restart qihuo
|
||
```
|
||
|
||
应用启动时会自动执行 SQLite 表结构迁移(`ALTER TABLE` 容错),一般无需手工改库。
|
||
|
||
### 首次启用 CTP 下单
|
||
|
||
1. 浏览器登录 → **系统设置** 确认 **模拟盘 · SimNow**
|
||
2. 打开 **下单监控** 页 → 点击 **连接 CTP**
|
||
3. 连接成功后:权益来自柜台、显示 CTP 持仓、可报单与可开仓品种筛选
|
||
|
||
详见 [TRADING.md](./TRADING.md)。
|
||
|
||
---
|
||
|
||
## PM2 常用命令
|
||
|
||
```bash
|
||
pm2 status # 查看状态
|
||
pm2 logs qihuo # 查看日志
|
||
pm2 logs qihuo --lines 100
|
||
pm2 restart qihuo # 重启
|
||
pm2 stop qihuo # 停止
|
||
pm2 delete qihuo # 删除进程
|
||
pm2 save # 保存进程列表
|
||
```
|
||
|
||
日志文件:
|
||
|
||
- `/opt/qihuo/logs/pm2-out.log`
|
||
- `/opt/qihuo/logs/pm2-error.log`
|
||
|
||
---
|
||
|
||
## 本地开发
|
||
|
||
```bash
|
||
git clone https://git.bz121.com/dekun/qihuo.git
|
||
cd qihuo
|
||
python3 -m venv venv
|
||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||
pip install -r requirements.txt
|
||
cp .env.example .env
|
||
python app.py
|
||
```
|
||
|
||
浏览器访问:`http://127.0.0.1:6600`
|
||
|
||
---
|
||
|
||
## 账号与密码
|
||
|
||
| 场景 | 操作 |
|
||
|------|------|
|
||
| 首次部署 | `.env` 中设置 `ADMIN_USERNAME` / `ADMIN_PASSWORD` 后启动 |
|
||
| 已部署后改 `.env` 密码 | 设 `ADMIN_SYNC_FROM_ENV=true`,`pm2 restart qihuo` |
|
||
| 网页改密码 | 登录 → 系统设置 |
|
||
| 忘记密码 | `cd /opt/qihuo && source venv/bin/activate && python reset_admin.py` |
|
||
|
||
账号数据在 `futures.db` 的 `settings` 表,不会仅因改 `.env` 自动更新(除非开启 `ADMIN_SYNC_FROM_ENV`)。
|
||
|
||
---
|
||
|
||
## 数据库与数据文件
|
||
|
||
| 路径 | 说明 |
|
||
|------|------|
|
||
| `/opt/qihuo/futures.db` | 主数据库,建议定期备份 |
|
||
| `/opt/qihuo/uploads/` | 复盘截图、自动 K 线图 |
|
||
| `/opt/qihuo/data/fee_rates.json` | 默认手续费表(可重载) |
|
||
|
||
备份示例:
|
||
|
||
```bash
|
||
cp /opt/qihuo/futures.db /opt/qihuo/futures.db.bak.$(date +%Y%m%d)
|
||
```
|
||
|
||
### 手工补列(极少需要)
|
||
|
||
若极老版本库缺少字段,可对照报错执行(新版本启动会自动迁移):
|
||
|
||
```bash
|
||
sqlite3 /opt/qihuo/futures.db "ALTER TABLE key_monitors ADD COLUMN sina_code TEXT;"
|
||
```
|
||
|
||
---
|
||
|
||
## Nginx 反向代理(可选)
|
||
|
||
将 6600 反代到 80/443,并配置 HTTPS:
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name your.domain.com;
|
||
|
||
location / {
|
||
proxy_pass http://127.0.0.1:6600;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 防火墙
|
||
|
||
若使用 `ufw`,开放端口:
|
||
|
||
```bash
|
||
ufw allow 6600/tcp
|
||
# 或使用 Nginx 时只开放 80/443
|
||
```
|
||
|
||
---
|
||
|
||
## 故障排查
|
||
|
||
| 现象 | 可能原因 | 处理 |
|
||
|------|----------|------|
|
||
| 无法访问 6600 | 服务未启动 / 防火墙 | `pm2 status`、`pm2 logs qihuo` |
|
||
| 登录失败 | 密码未同步 | 网页改密或 `reset_admin.py` |
|
||
| 现价一直 `--` | 新浪网络不可达 | 检查服务器能否访问 `hq.sinajs.cn` |
|
||
| 关键位 500 | 缺 `sina_code` 列 | `git pull` 重启;或手工 `ALTER TABLE` |
|
||
| K 线生成失败 | matplotlib 未装 | `pip install matplotlib==3.9.2` |
|
||
| 手续费同步失败 | akshare 异常 | 使用「重载 JSON」或检查 akshare |
|
||
| **未安装 vnpy / vnpy_ctp** | 依赖未装或编译失败 | 见下方「CTP / vnpy 故障排查」 |
|
||
| **CTP 连接超时** | SimNow 地址/账号/非交易时段 | 核对 `.env` 与 SimNow 官网前置 |
|
||
| **下单监控无持仓** | 未连接 CTP 或确实无仓 | 先点「连接 CTP」 |
|
||
| **`Could not resolve host`** | 服务器 DNS 故障 | 配置 systemd-resolved 公共 DNS,见下方 |
|
||
| `database is locked` | SQLite 并发 | 更新代码后重启 |
|
||
| `git pull` 冲突 | 本地有修改 / SCP 部署 | `git fetch && git reset --hard origin/main` |
|
||
|
||
查看应用是否在监听:
|
||
|
||
```bash
|
||
ss -tlnp | grep 6600
|
||
```
|
||
|
||
### DNS 无法解析(git / curl 均失败)
|
||
|
||
若 `curl cip.cc` 或 `git pull` 报 `Could not resolve host`:
|
||
|
||
```bash
|
||
mkdir -p /etc/systemd/resolved.conf.d
|
||
cat > /etc/systemd/resolved.conf.d/dns.conf <<'EOF'
|
||
[Resolve]
|
||
DNS=223.5.5.5 8.8.8.8
|
||
FallbackDNS=1.1.1.1
|
||
EOF
|
||
systemctl restart systemd-resolved
|
||
resolvectl flush-caches
|
||
```
|
||
|
||
验证:`resolvectl query git.bz121.com`、`curl cip.cc`
|
||
|
||
---
|
||
|
||
页面提示 **「未安装 vnpy / vnpy_ctp」** 表示 Python 环境未成功安装 CTP 网关,下单与柜台持仓不可用(看盘、策略、复盘仍可用)。
|
||
|
||
**1. 安装依赖**
|
||
|
||
```bash
|
||
cd /opt/qihuo
|
||
source venv/bin/activate
|
||
apt install -y build-essential python3-dev pkg-config # 首次需要
|
||
pip install -r requirements.txt
|
||
python -c "from vnpy_ctp import CtpGateway; print('OK')"
|
||
pm2 restart qihuo
|
||
```
|
||
|
||
**2. 配置 SimNow(`.env`)**
|
||
|
||
注册与查投资者代码见 [SIMNOW.md](./SIMNOW.md)。填写 `SIMNOW_USER`(投资者代码)、`SIMNOW_PASSWORD`,前置地址以 SimNow 官网为准。
|
||
|
||
**3. 连接**
|
||
|
||
登录系统 → **下单监控** → **连接 CTP**。成功则顶栏显示「CTP 已连接」,权益变为 SimNow 账户资金。
|
||
|
||
**4. 常见错误**
|
||
|
||
| 日志/现象 | 处理 |
|
||
|-----------|------|
|
||
| `pip install vnpy_ctp` 编译失败 / `Python dependency not found` | 安装 `build-essential python3-dev pkg-config` 后重试 |
|
||
| CTP 连接超时 | 检查前置 IP、端口、SimNow 是否维护、是否在允许连接时段 |
|
||
| 连接后立即崩溃 `locale::facet::_S_create_c_locale` | CTP 需 **zh_CN.GB18030**:`sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen && locale-gen zh_CN.GB18030`,再 `pm2 restart qihuo --update-env` |
|
||
| 服务器 `180.168.146.187` 超时 | 换 SimNow 备用前置 `182.254.243.31:30001/30011`(见 [SIMNOW.md](./SIMNOW.md)) |
|
||
| 已连接但下单拒单 | 检查合约代码、价格精度、是否有足够保证金 |
|
||
|
||
---
|
||
|
||
## 安全建议
|
||
|
||
1. 部署后立即修改默认密码
|
||
2. 勿将 `.env`、`futures.db` 提交到公开仓库
|
||
3. 生产环境使用 HTTPS + 限制访问 IP
|
||
4. 定期备份 `futures.db` 与 `uploads/`
|
||
|
||
---
|
||
|
||
## 目录结构(部署后)
|
||
|
||
```
|
||
/opt/qihuo/
|
||
├── app.py
|
||
├── vnpy_bridge.py # CTP 执行层
|
||
├── recommend_store.py # 可开仓品种缓存
|
||
├── recommend_stream.py # 可开仓品种 SSE 推送
|
||
├── venv/
|
||
├── futures.db
|
||
├── .env
|
||
├── logs/
|
||
│ ├── pm2-out.log
|
||
│ └── pm2-error.log
|
||
├── uploads/
|
||
├── data/fee_rates.json
|
||
├── ecosystem.config.cjs
|
||
├── deploy.sh
|
||
├── requirements.txt # 含 vnpy、vnpy_ctp
|
||
└── docs/
|
||
├── FEATURES.md
|
||
├── DEPLOY.md
|
||
└── TRADING.md
|
||
```
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- [功能说明文档](./FEATURES.md)
|
||
- [SimNow 注册与接入说明](./SIMNOW.md)
|
||
- [手续费与导航设置](./FEES.md)
|
||
- [交易与 SimNow 配置](./TRADING.md)
|
||
- [README](../README.md)
|