# 部署文档 国内期货 · 交易复盘系统 — 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` | 默认手续费表(可重载) | | `/root/qihuo_backup/` | 系统自动备份目录(`.tar.gz`) | ### 自动备份(推荐) 系统设置 → **数据备份与恢复**: - 默认每天 03:00 自动备份到 `/root/qihuo_backup` - 含 `futures.db` 与 `uploads/`,可在其他服务器恢复 - 设置页可立即备份、下载历史压缩包 完整说明见 **[BACKUP.md](./BACKUP.md)**。 ### 手工备份(备选) ```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. 定期备份:系统设置页自动备份至 `/root/qihuo_backup`,或见 [BACKUP.md](docs/BACKUP.md) --- ## 目录结构(部署后) ``` /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)