Files
qihuo/docs/DEPLOY.md
T

20 KiB
Raw Blame History

部署文档

国内期货 · 交易复盘系统 — Ubuntu 服务器部署、更新与运维说明。


代码发布铁律(强制,不容置疑)

所有代码变更必须且只能按以下三步执行,不得跳过、不得变通:

步骤 在哪里 做什么
1. 本地修改 开发机 / 本仓库工作区 改代码、自测
2. 提交仓库 git.bz121.com git addgit commitgit push origin main(或约定分支)
3. 更新服务器 /opt/qihuo git fetch + git reset --hard origin/main(或 git pull)→ 依赖/迁移 → pm2 restart

严禁事项

  • 禁止scprsync、SFTP、手工复制等方式把 .py / .js / .html / 模板 / 静态资源 直接覆盖 到服务器。
  • 禁止 在服务器上 vim 改业务代码后长期不提交仓库(.env、日志、上传文件除外)。
  • 禁止 「服务器上先改一版、本地以后再补提交」——服务器代码必须与远端 Git 完全一致

违反上述规则会导致:git pull 冲突、Web 与 Worker 版本不一致、问题无法复现、回滚困难。一律视为部署事故。

服务器唯一合法更新命令

代码已推送到远端后,在服务器执行:

cd /opt/qihuo
git fetch origin
git reset --hard origin/main
source venv/bin/activate
pip install -r requirements.txt
python scripts/run_schema_migrate.py
pm2 restart ecosystem.config.cjs --update-env
pm2 save

或使用 bash deploy.sh(内部同样通过 Git 拉取,见下文)。

数据与配置(不受 Git 管理)

以下文件 git pull 更新,卸载/重装时须 单独备份与恢复

  • /opt/qihuo/.env
  • /opt/qihuo/futures.dbSQLite)或 PostgreSQL 数据
  • /opt/qihuo/uploads/
  • /opt/qihuo/backups/(若有)

部署概要

项目 默认值
部署目录 /opt/qihuo
运行用户 root(与 deploy.sh / PM2 配置一致)
Web 端口 6600(对外)
CTP Worker 端口 6601(仅 127.0.0.1,Web 进程 IPC 调用,勿对外开放)
进程管理 PM2qihuoFlask Web+ qihuo-ctpCTP / vn.py 独立进程)
数据库 生产推荐 PostgreSQL(见 POSTGRES.md);未配置 DATABASE_URL 时使用 SQLite futures.db
仓库 https://git.bz121.com/dekun/qihuo.git

进程架构(2026-03 起)

PM2 应用 角色 说明
qihuo WebQIHUO_CTP_ROLE=client Flask、页面、API、数据库;通过 HTTP 调用本机 Worker
qihuo-ctp WorkerQIHUO_CTP_ROLE=worker 唯一 加载 vn.py / vnpy_ctp;CTP 连接、报单、持仓回调、止盈止损 tick、滚仓监控

Web 进程崩溃或重启 不会 直接带走 CTP 原生连接;Worker 重启后 Web 会自动通过 IPC 恢复读写。两个进程的 Token 须一致(见 ecosystem.config.cjsQIHUO_CTP_WORKER_TOKEN)。


环境要求

  • 系统Ubuntu 20.04+(推荐)
  • Python3.10+vnpy_ctp 要求 ≥3.10
  • Node.js + PM2:进程守护与开机自启
  • 编译工具(安装 vnpy_ctp 时需要):build-essentialpython3-devpkg-config
  • 网络
    • hq.sinajs.cn(新浪行情)
    • 企业微信 API(若启用推送)
    • git.bz121.com(拉取代码)
    • pypi.orgpip 安装依赖)
    • SimNow / 期货公司 CTP 前置地址(下单与持仓,见下文)

一键部署(推荐)

root 登录服务器后执行:

cd /opt/qihuo
# 若目录不存在,先克隆:
# git clone https://git.bz121.com/dekun/qihuo.git /opt/qihuo

bash deploy.sh

deploy.sh 会自动完成:

  1. 安装系统依赖:python3gitbuild-essentialpython3-devpkg-configlocalesnetcat-openbsdpm2
  2. 时区设为 Asia/Shanghai(与 SimNow 交易时段一致)
  3. locale:生成 zh_CN.GB18030zh_CN.UTF-8CTP 登录必需,缺则进程崩溃)
  4. git pullgit clone/opt/qihuo
  5. 创建/保留虚拟环境 venvpip 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 ecosystem.config.cjs --update-env 或首次 pm2 start ecosystem.config.cjs,并 pm2 save(同时启动 qihuoqihuo-ctp

部署完成后访问:http://<服务器IP>:6600

PostgreSQL 生产库(推荐)

消除 SQLite 并发 database is locked,一键安装 PostgreSQL 并迁移:

cd /opt/qihuo
git pull
# 新装 PostgreSQL + 空库
sudo bash scripts/deploy_postgres.sh
# 从现有 futures.db 迁移
MIGRATE_SQLITE=1 sudo bash scripts/deploy_postgres.sh

完整说明、手动步骤、备份恢复见 POSTGRES.md

再次部署只需 cd /opt/qihuo && bash deploy.sh,无需手工装 locale 或改前置地址。


服务器卸载与全新部署(Git 唯一来源)

当服务器代码被 SCP 弄乱、版本不可信、或需要与仓库 完全对齐 时,按本节 卸载后重装。全程 通过 Git 获取代码,不得 SCP 复制业务文件。

1. 备份(必做)

# 在服务器上
cp /opt/qihuo/.env /root/qihuo.env.bak
# SQLite
cp /opt/qihuo/futures.db /root/futures.db.bak 2>/dev/null || true
# PostgreSQL 见 POSTGRES.md 备份命令
tar czf /root/qihuo_uploads.bak.tar.gz -C /opt/qihuo uploads 2>/dev/null || true

2. 卸载 PM2 与代码目录

pm2 stop qihuo qihuo-ctp 2>/dev/null || true
pm2 delete qihuo qihuo-ctp 2>/dev/null || true
pm2 save
rm -rf /opt/qihuo

不删除 /root/qihuo.env.bak/root/futures.db.bak 等备份。

3. 从 Git 全新克隆并部署

git clone https://git.bz121.com/dekun/qihuo.git /opt/qihuo
cd /opt/qihuo
cp /root/qihuo.env.bak .env
# SQLite 恢复(若使用)
cp /root/futures.db.bak futures.db 2>/dev/null || true
bash deploy.sh

4. 验收

cd /opt/qihuo && git log -1 --oneline   # 须与远端 main 最新提交一致
pm2 status                                 # qihuo、qihuo-ctp 均为 online

浏览器访问 http://<服务器IP>:6600 登录验证。

此后所有更新 走上文「代码发布铁律」三步,禁止 再使用 SCP 更新代码。


手动部署

1. 安装系统依赖

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-essentialpython3-devpkg-config 用于编译安装 vnpy_ctpCTP 网关)。Meson 通过 pkg-config 查找 Python 头文件;缺 pkg-config 时会报 Python dependency not found

2. 克隆代码

git clone https://git.bz121.com/dekun/qihuo.git /opt/qihuo
cd /opt/qihuo

3. Python 虚拟环境与依赖

python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

依赖已包含 vnpyvnpy_ctpCTP 报单)、akshare(手续费同步)。安装完成后可验证:

python -c "from vnpy_ctp import CtpGateway; print('vnpy_ctp OK')"

若提示找不到模块,查看本文「CTP / vnpy 故障排查」一节。

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 simulationSimNow/ live(实盘)
QIHUO_CTP_WORKER_TOKEN Web ↔ Worker IPC 鉴权(默认见 ecosystem.config.cjs,生产建议改随机串并保持两进程一致)
QIHUO_CTP_WORKER_URL Web 侧 Worker 地址,默认 http://127.0.0.1:6601
DATABASE_URL PostgreSQL 连接串(可选,见 POSTGRES.md

示例:

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 官网 核对 7×24 或交易时段地址。

6. PM2 启动

cd /opt/qihuo
pm2 start ecosystem.config.cjs    # 启动 qihuo + qihuo-ctp
pm2 save
pm2 startup   # 按提示执行命令,实现开机自启

确认两个进程均为 online

pm2 status
# 应看到 qihuo 与 qihuo-ctp

7. 创建日志目录(若不存在)

mkdir -p /opt/qihuo/logs /opt/qihuo/uploads

更新部署

强制流程:本地修改 → git push → 服务器 git fetch && git reset --hard origin/main → 迁移 → pm2 restart
禁止 SCP 复制代码。 详见上文 代码发布铁律

代码已推送后,在服务器执行:

cd /opt/qihuo
git fetch origin
git reset --hard origin/main
source venv/bin/activate
pip install -r requirements.txt
python scripts/run_schema_migrate.py
pm2 restart ecosystem.config.cjs --update-env
pm2 save

同时重启 qihuoqihuo-ctp。仅 pm2 restart qihuo 会导致 Web 与 Worker 代码/协议不一致。

若服务器曾用 SCP 覆盖文件导致 git pull 冲突,用 git reset --hard origin/main 与远端对齐。

vnpy_ctp 安装失败(常见于缺少编译环境):

apt install -y build-essential python3-dev pkg-config
source venv/bin/activate
pip install --no-cache-dir vnpy vnpy_ctp
pm2 restart ecosystem.config.cjs --update-env

应用启动时会自动执行 SQLite 表结构迁移(ALTER TABLE 容错),一般无需手工改库。

首次启用 CTP 下单

  1. 浏览器登录 → 系统设置 确认 模拟盘 · SimNow
  2. 确认 pm2 statusqihuo-ctp 为 online
  3. 打开 下单监控 页 → 点击 连接 CTP(或由后台自动重连)
  4. 连接成功后:权益来自柜台、显示 CTP 持仓、可报单与可开仓品种筛选

CTP 连接与重连在 qihuo-ctp Worker 内执行;页面仅轮询状态,切换页面不会重复发起连接

详见 TRADING.md


PM2 常用命令

pm2 status                    # 查看 qihuo / qihuo-ctp 状态
pm2 logs qihuo                # Web 日志
pm2 logs qihuo-ctp            # CTP Worker 日志
pm2 logs qihuo --lines 100
pm2 restart ecosystem.config.cjs --update-env   # 同时重启两个进程(推荐)
pm2 restart qihuo             # 仅重启 Web
pm2 restart qihuo-ctp         # 仅重启 CTP WorkerWeb 应仍可访问)
pm2 stop qihuo                # 停止 Web
pm2 delete qihuo              # 删除 Web 进程
pm2 save                      # 保存进程列表

日志文件:

  • /opt/qihuo/logs/pm2-out.logpm2-error.log — Webqihuo
  • /opt/qihuo/logs/pm2-ctp-out.logpm2-ctp-error.log — CTP Workerqihuo-ctp

本地开发

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=truepm2 restart ecosystem.config.cjs --update-env
网页改密码 登录 → 系统设置
忘记密码 cd /opt/qihuo && source venv/bin/activate && python reset_admin.py

账号数据在 futures.dbsettings 表,不会仅因改 .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.dbuploads/,可在其他服务器恢复
  • 设置页可立即备份、下载历史压缩包

完整说明见 BACKUP.md

手工备份(备选)

cp /opt/qihuo/futures.db /opt/qihuo/futures.db.bak.$(date +%Y%m%d)

手工补列(极少需要)

若极老版本库缺少字段,可对照报错执行(新版本启动会自动迁移):

sqlite3 /opt/qihuo/futures.db "ALTER TABLE key_monitors ADD COLUMN sina_code TEXT;"

Nginx 反向代理(可选)

将 6600 反代到 80/443,并配置 HTTPS

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,开放端口:

ufw allow 6600/tcp
# 或使用 Nginx 时只开放 80/443

故障排查

现象 可能原因 处理
无法访问 6600 服务未启动 / 防火墙 pm2 statuspm2 logs qihuo
qihuo-ctp 不在线 / 反复重启 vnpy 崩溃、SimNow 前置不可达、locale 缺失 pm2 logs qihuo-ctp --lines 200;核对 SimNow 前置与 zh_CN.GB18030
页面显示 CTP 未连接但 Worker 正常 Web 与 Worker Token 不一致 检查 ecosystem.config.cjs 两进程 QIHUO_CTP_WORKER_TOKEN 相同后重启
API 报 CTP worker unavailable Worker 未启动或 6601 不可达 curl -s http://127.0.0.1:6601/healthpm2 restart qihuo-ctp
登录失败 密码未同步 网页改密或 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 并发 推荐改 PostgreSQLMIGRATE_SQLITE=1 bash scripts/deploy_postgres.sh,见 POSTGRES.md
git pull 冲突 曾用 SCP 覆盖文件(禁止 服务器卸载与全新部署git reset --hard origin/main 与远端对齐

查看应用是否在监听:

ss -tlnp | grep 6600

DNS 无法解析(git / curl 均失败)

curl cip.ccgit pullCould not resolve host

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.comcurl cip.cc


页面提示 「未安装 vnpy / vnpy_ctp」 表示 Python 环境未成功安装 CTP 网关,下单与柜台持仓不可用(看盘、策略、复盘仍可用)。

1. 安装依赖

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 ecosystem.config.cjs --update-env

2. 配置 SimNow.env

注册与查投资者代码见 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.GB18030sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen && locale-gen zh_CN.GB18030,再 pm2 restart ecosystem.config.cjs --update-env
服务器 180.168.146.187 超时 换 SimNow 备用前置 182.254.243.31:30001/30011(见 SIMNOW.md
已连接但下单拒单 检查合约代码、价格精度、是否有足够保证金

安全建议

  1. 部署后立即修改默认密码
  2. 勿将 .envfutures.db 提交到公开仓库
  3. 生产环境使用 HTTPS + 限制访问 IP
  4. 定期备份:系统设置页自动备份至 /root/qihuo_backup,或见 BACKUP.md

目录结构(部署后)

/opt/qihuo/
├── app.py
├── vnpy_bridge.py          # CTP 桥接(Web=IPC 代理,Worker=原生 vn.py
├── ctp_ipc_client.py       # Web → Worker HTTP 客户端
├── ctp_worker.py           # 独立 CTP Worker 入口(PM2: qihuo-ctp
├── recommend_store.py      # 可开仓品种缓存
├── recommend_stream.py     # 可开仓品种 SSE 推送
├── venv/
├── futures.db
├── .env
├── logs/
│   ├── pm2-out.log
│   ├── pm2-error.log
│   ├── pm2-ctp-out.log
│   └── pm2-ctp-error.log
├── uploads/
├── data/fee_rates.json
├── ecosystem.config.cjs    # PM2qihuo + qihuo-ctp
├── deploy.sh
├── requirements.txt        # 含 vnpy、vnpy_ctp
└── docs/
    ├── FEATURES.md
    ├── DEPLOY.md
    └── TRADING.md

相关文档