26 KiB
06 - NAS 基础设施部署全纪录
版本: v1.0 日期: 2026-05-03 作者: 姜维(平台总督)
1. 概述
本文档记录 sanguo_vnpy 项目在群晖 NAS(192.168.2.154)上的完整部署方案,包括需求、设计、构建、部署、测试、运维全流程,以及历史踩坑记录。
2. 需求定义
2.1 基础设施需求
| 编号 | 需求 | 优先级 | 状态 |
|---|---|---|---|
| INF-001 | NAS Docker 容器化部署 vnpy 环境 | P0 | ✅ |
| INF-002 | 回测服务 API 化(HTTP 接口) | P0 | ✅ |
| INF-003 | Jupyter Lab 开发环境 | P1 | ✅ |
| INF-004 | SSH 运维通道 | P1 | ✅ |
| INF-005 | 数据自动增量更新 | P1 | ✅ |
| INF-006 | 容器异常自动重启 | P1 | ✅ |
| INF-007 | VS Code Server Web IDE | P2 | ❌ 跳过(网络问题) |
2.2 硬件环境
| 项目 | 规格 |
|---|---|
| NAS 型号 | 群晖 DS220+ |
| NAS IP | 192.168.2.154 |
| CPU 架构 | x86_64 |
| 内核版本 | Linux 3.10.108(重要:影响 SSH 选型) |
| Docker | 群晖套件 Docker 20.x |
| 存储路径 | /volume1/stock/ |
2.3 网络拓扑
Mac Mini (192.168.2.153) 群晖 NAS (192.168.2.154)
┌──────────────────────┐ ┌─────────────────────────────────────┐
│ OpenClaw Gateway │ │ Docker: sanguo_vnpy 容器 │
│ 开发机/调度中心 │ 局域网 │ ┌─ Jupyter Lab (8888) │
│ │◄──────────────►│ ├─ 回测服务 (8088) │
│ /Volumes/stock/ │ SMB 挂载 │ ├─ SSH/dropbear (22→2222) │
│ (NAS SMB 挂载) │◄──────────────►│ └─ WebTrader (8000) 预留 │
└──────────────────────┘ │ │
│ 数据库: quant_trading.db (1.4GB) │
│ 原始数据: /volume1/stock/A股数据/ │
└─────────────────────────────────────┘
3. 详细设计
3.1 Docker 镜像设计
3.1.1 镜像分层策略
镜像: sanguo_vnpy:with-scripts (4.08GB)
┌─────────────────────────────────────────┐
│ Layer 1: python:3.10-slim (基础镜像) │ ← 永不重构建
├─────────────────────────────────────────┤
│ Layer 2: 系统工具 (git/curl/vim/sudo等) │ ← 极少重构建
├─────────────────────────────────────────┤
│ Layer 3: 编译工具链 (build-essential) │ ← 极少重构建
├─────────────────────────────────────────┤
│ Layer 4: 图形库 + OpenSSH │ ← 极少重构建
├─────────────────────────────────────────┤
│ Layer 5: pip 基础依赖 (vnpy/numpy等) │ ← 低频变更
│ requirements-base.txt │
├─────────────────────────────────────────┤
│ Layer 6: pip 额外依赖 (akshare等) │ ← 可能变更
│ requirements-extra.txt │
├─────────────────────────────────────────┤
│ Layer 7: 用户配置 + scripts 拷贝 │ ← 每次构建
└─────────────────────────────────────────┘
关键原则:
- 分层构建利用 Docker 缓存,修改额外依赖不需要重装 vnpy/numpy
with-scripts镜像在latest基础上增加了/app/scripts/backtest_service/目录- 禁止随意重构建镜像,优先通过 volume 挂载更新代码
3.1.2 当前镜像版本
| 镜像 | 大小 | 构建时间 | 说明 |
|---|---|---|---|
sanguo_vnpy:latest |
4.08GB | 2026-04-11 | 基础镜像(无回测服务代码) |
sanguo_vnpy:with-scripts |
4.08GB | 2026-04-28 | 含回测服务代码(当前使用) |
3.2 容器运行设计
3.2.1 容器启动参数
docker run -d \
--name sanguo_vnpy \
--restart unless-stopped \
--privileged \
-p 2222:22 \
-p 8000:8000 \
-p 8088:8088 \
-p 8888:8888 \
-v /volume1/stock/sanguo_vnpy/bt-service:/app/scripts/backtest_service:ro \
-v /volume1/stock/sanguo_vnpy/entrypoint.sh:/app/entrypoint.sh:ro \
sanguo_vnpy:with-scripts
参数说明:
| 参数 | 说明 | 选型理由 |
|---|---|---|
--restart unless-stopped |
异常自动重启 | NAS 重启后自动恢复服务 |
--privileged |
特权模式 | 群晖内核 3.10 不支持 seccomp,SSH dropbear 需要特权执行 |
-p 2222:22 |
SSH 端口映射 | 避免和 NAS 自身 SSH 冲突 |
-v bt-service:ro |
回测服务代码挂载 | 代码更新不需要重建镜像 |
-v entrypoint.sh:ro |
启动脚本挂载 | 配置变更不需要重建镜像 |
3.2.2 Volume 挂载设计
| NAS 路径 | 容器路径 | 权限 | 用途 |
|---|---|---|---|
/volume1/stock/sanguo_vnpy/bt-service/ |
/app/scripts/backtest_service/ |
ro | 回测服务代码 |
/volume1/stock/sanguo_vnpy/entrypoint.sh |
/app/entrypoint.sh |
ro | 容器启动脚本 |
设计理由:代码通过 volume 挂载(非 commit),修改后 docker restart 即生效,无需重建镜像。
3.2.3 端口映射
| 容器端口 | NAS 端口 | 服务 | 状态 |
|---|---|---|---|
| 22 | 2222 | SSH (dropbear) | ✅ 运行 |
| 8000 | 8000 | WebTrader (预留) | — |
| 8088 | 8088 | 回测 API (uvicorn) | ✅ 运行 |
| 8888 | 8888 | Jupyter Lab | ✅ 运行 |
3.3 服务启动流程(entrypoint.sh)
entrypoint.sh 执行顺序:
1. pip3 install vnpy_ctastrategy vnpy_sqlite # 运行时依赖(容器层无持久化)
2. apt-get install dropbear-bin # SSH 替代方案
3. 生成 SSH host keys + 配置 dropbear # SSH 服务启动
4. jupyter lab & # Jupyter 开发环境
5. uvicorn backtest_service.main:app & # 回测 API 服务
6. 健康检查 # 验证服务就绪
7. tail -f /dev/null # 保持容器运行
注意事项:
- pip 包安装在容器可写层,容器重启后丢失,每次启动自动重装
- dropbear 在 entrypoint 中自动安装,无需包含在镜像中
- 回测服务代码通过 volume 挂载,代码更新
docker restart即生效
3.4 数据层设计
3.4.1 数据目录结构(NAS)
/volume1/stock/
├── A股数据/
│ ├── 日线数据/daily/
│ │ ├── 2010/ # 按年份组织,每年 ~5000+ parquet 文件
│ │ ├── 2011/
│ │ └── ... /2026/
│ ├── 分钟线数据/
│ ├── 财务数据/financial/
│ └── stock_info/ # 股票基础信息 CSV/JSON
│
├── sanguo_vnpy/
│ ├── data/
│ │ ├── quant_trading.db # vnpy 交易数据库 (1.4GB)
│ │ ├── quant_trading.db.bak # 备份
│ │ └── all_stocks.csv # 股票列表
│ ├── bt-service/ # 回测服务代码 (volume 挂载)
│ ├── entrypoint.sh # 容器启动脚本 (volume 挂载)
│ ├── docker/ # Dockerfile + requirements
│ ├── scripts/ # 工具脚本
│ ├── strategies/ # 策略代码
│ └── config/ # 配置文件
│
├── 回测结果/ # 回测产出
├── 代码库/ # 代码归档
└── 临时文件/
3.4.2 vnpy 交易数据库
| 项目 | 详情 |
|---|---|
| 文件 | quant_trading.db(SQLite) |
| 大小 | 1.4 GB |
| 位置 | /volume1/stock/sanguo_vnpy/data/ |
| 表 | dbbardata(K线数据)、dbbaroverview(5191条概览) |
| 数据类型 | 日线(interval=d) |
| 时间范围 | 2010-01-04 ~ 2026-03-27 |
| 覆盖股票 | 5191 只(SSE + SZSE 全 A 股) |
3.4.3 数据增量更新
Mac Mini cron (每交易日 15:30)
→ daily_update.sh
→ 检查 NAS SMB 是否挂载
→ updater.py(腾讯 K 线 API → DB 增量写入)
→ 清理 30 天前日志
- 数据源:腾讯 K 线 API(主源)
- 写入方式:Mac 本机通过 SMB 直接读写 NAS 上的 DB 文件
- 兜底:NAS 未挂载时脚本检测到后跳过,不会损坏数据
- 待改进:改为容器内 API 触发,避免 SMB 依赖
4. 构建指南
4.1 构建基础镜像(极少执行)
# 在 NAS 上执行
cd /volume1/stock/sanguo_vnpy
# 基础镜像
docker build -t sanguo_vnpy:latest -f docker/Dockerfile .
# 含回测代码的镜像(推荐)
# 在 Dockerfile 构建后,将 bt-service 目录拷入镜像
docker build -t sanguo_vnpy:with-scripts -f docker/Dockerfile .
⚠️ 纪律:非必要不构建。代码更新走 volume 挂载 + docker restart。
4.2 依赖管理
| 文件 | 内容 | 变更频率 |
|---|---|---|
requirements-base.txt |
vnpy, numpy, pandas, scipy, matplotlib, sklearn | 低 |
requirements-extra.txt |
akshare, tushare, debugpy, ipywidgets | 中 |
entrypoint.sh pip install |
vnpy_ctastrategy, vnpy_sqlite | 每次启动 |
5. 部署指南
5.1 首次部署
# 1. 确保 NAS SSH 可用
ssh admin@192.168.2.154
# 2. 确认镜像存在
/usr/local/bin/docker images sanguo_vnpy
# 3. 启动容器
/usr/local/bin/docker run -d \
--name sanguo_vnpy \
--restart unless-stopped \
--privileged \
-p 2222:22 \
-p 8000:8000 \
-p 8088:8088 \
-p 8888:8888 \
-v /volume1/stock/sanguo_vnpy/bt-service:/app/scripts/backtest_service:ro \
-v /volume1/stock/sanguo_vnpy/entrypoint.sh:/app/entrypoint.sh:ro \
sanguo_vnpy:with-scripts
# 4. 等待启动完成(约 40 秒,pip install 需要时间)
sleep 40
# 5. 验证
curl http://192.168.2.154:8088/api/backtest/health
sshpass -p sanguo123 ssh -p 2222 vnpy@192.168.2.154 "echo OK"
5.2 代码更新(不需要重建镜像)
# 1. 修改 NAS 上的代码(通过 SMB 挂载)
# /Volumes/stock/sanguo_vnpy/bt-service/ 下的文件
# 2. 重启容器
ssh admin@192.168.2.154 "/usr/local/bin/docker restart sanguo_vnpy"
# 3. 等待启动完成
sleep 40
# 4. 验证
curl http://192.168.2.154:8088/api/backtest/health
5.3 完全重建容器
当需要修改容器启动参数(端口、volume、安全选项)时:
ssh admin@192.168.2.154 "/usr/local/bin/docker stop sanguo_vnpy && \
/usr/local/bin/docker rm sanguo_vnpy && \
/usr/local/bin/docker run -d \
--name sanguo_vnpy \
--restart unless-stopped \
--privileged \
-p 2222:22 -p 8000:8000 -p 8088:8088 -p 8888:8888 \
-v /volume1/stock/sanguo_vnpy/bt-service:/app/scripts/backtest_service:ro \
-v /volume1/stock/sanguo_vnpy/entrypoint.sh:/app/entrypoint.sh:ro \
sanguo_vnpy:with-scripts"
注意:重建容器会丢失容器内 /app/backtest_jobs/ 的历史任务数据(如有)。
6. 测试验证
6.1 服务健康检查
# 回测服务
curl http://192.168.2.154:8088/api/backtest/health
# 预期: {"code":0,"msg":"ok","data":{...}}
# Jupyter Lab
curl -s -o /dev/null -w "%{http_code}" http://192.168.2.154:8888/
# 预期: 302
# SSH
sshpass -p sanguo123 ssh -o StrictHostKeyChecking=no -p 2222 vnpy@192.168.2.154 "echo OK"
# 预期: OK
# Swagger 文档
curl -s -o /dev/null -w "%{http_code}" http://192.168.2.154:8088/docs
# 预期: 200
6.2 容器重启自动恢复测试
# 重启容器
ssh admin@192.168.2.154 "/usr/local/bin/docker restart sanguo_vnpy"
sleep 40
# 验证所有服务
curl http://192.168.2.154:8088/api/backtest/health
sshpass -p sanguo123 ssh -p 2222 vnpy@192.168.2.154 "echo OK"
6.3 回测功能测试
curl -X POST http://192.168.2.154:8088/api/backtest/submit \
-H "Content-Type: application/json" \
-d '{
"strategy_name": "test_ma",
"strategy_code": "from vnpy_ctastrategy import CtaTemplate\n\nclass TestMA(CtaTemplate):\n fast_window = 5\n slow_window = 20\n parameters = [\"fast_window\", \"slow_window\"]\n variables = []\n def on_init(self): pass\n def on_start(self): pass\n def on_stop(self): pass\n def on_bar(self, bar): pass",
"symbol": "000001.SZSE",
"interval": "d",
"start_date": "2025-01-01",
"end_date": "2025-12-31",
"capital": 1000000,
"engine_type": "cta"
}'
7. 服务地址汇总
7.1 用户访问地址
| 服务 | 地址 | 账号 | 说明 |
|---|---|---|---|
| Jupyter Lab | http://192.168.2.154:8888 |
token: sanguo123 |
Python 开发环境 |
| 回测 API | http://192.168.2.154:8088 |
— | 回测任务提交/查询 |
| 回测文档 | http://192.168.2.154:8088/docs |
— | Swagger 交互式文档 |
| SSH | ssh -p 2222 vnpy@192.168.2.154 |
vnpy / sanguo123 |
运维通道(dropbear) |
7.2 管理命令(在 NAS 上执行)
# 查看容器状态
/usr/local/bin/docker ps | grep sanguo_vnpy
# 查看容器日志
/usr/local/bin/docker logs sanguo_vnpy --tail 50
# 重启容器
/usr/local/bin/docker restart sanguo_vnpy
# 进入容器
/usr/local/bin/docker exec -it sanguo_vnpy bash
# 查看容器内进程
/usr/local/bin/docker exec sanguo_vnpy ps aux
7.3 Mac 端访问命令
# SSH 连接
sshpass -p sanguo123 ssh -p 2222 vnpy@192.168.2.154
# 回测健康检查
curl http://192.168.2.154:8088/api/backtest/health
# NAS Docker 管理(通过 admin SSH)
ssh admin@192.168.2.154 "/usr/local/bin/docker ps"
8. 运维手册
8.1 日常巡检
# 一键检查所有服务
echo "=== 回测 ===" && curl -s http://192.168.2.154:8088/api/backtest/health && \
echo "" && echo "=== Jupyter ===" && curl -s -o /dev/null -w "HTTP %{http_code}" http://192.168.2.154:8888/ && \
echo "" && echo "=== SSH ===" && sshpass -p sanguo123 ssh -o ConnectTimeout=3 -o StrictHostKeyChecking=no -p 2222 vnpy@192.168.2.154 "echo OK" 2>&1
8.2 故障排查
| 症状 | 检查方法 | 可能原因 | 解决方案 |
|---|---|---|---|
| API 无响应 | curl :8088/health |
uvicorn 未启动或已挂 | docker restart |
| SSH 连接被拒 | ssh -p 2222 vnpy@NAS |
dropbear 未启动 | docker exec -u root sanguo_vnpy bash -c 'dropbear -R -B -p 22' |
| 容器未运行 | docker ps |
NAS 重启或异常 | docker start sanguo_vnpy |
| pip 安装超时 | 查看容器日志 | NAS 网络问题 | 等待网络恢复后 restart |
| 数据更新失败 | cat /Volumes/stock/.../logs/cron.log |
NAS SMB 未挂载 | 手动挂载后重跑 |
8.3 数据备份
# vnpy DB 备份
cp /Volumes/stock/sanguo_vnpy/data/quant_trading.db \
/Volumes/stock/sanguo_vnpy/data/quant_trading.db.bak.$(date +%Y%m%d)
9. 历史 Q&A 与踩坑记录
⚠️ 安全提示:本文档中出现的 SSH 密码(sanguo123)仅限内网使用,严禁通过端口转发等方式暴露到公网。
Q1: SSH 为什么不能用 OpenSSH,要用 dropbear?
问题现象:SSH 连接返回 Connection closed 或 Connection reset,反复修过多次,每次重建容器就复发。
排查过程:
ssh -vvv → "kex_exchange_identification: banner line 0: Not allowed at this time"
→ 以为是 PAM 问题 → 关闭 UsePAM → 还是挂
sshd -ddd → "ssh_sandbox_child: prctl(PR_SET_SECCOMP): Invalid argument"
→ mm_reap: preauth child terminated by signal 25
根因:群晖 NAS 内核版本 3.10.108,不支持 prctl(PR_SET_SECCOMP) 系统调用。OpenSSH 10.0 的 sshd-auth 子进程硬编码使用 seccomp-bpf sandbox,在认证阶段调用 prctl(PR_SET_SECCOMP) 失败(EINVAL),preauth 子进程被信号 25 杀死。
尝试过的方案:
- ❌ 创建
/var/run/utmp— 只修了 symptom,不解决 sandbox - ❌ 创建 sshd 系统用户 — 解决了
Privilege separation user does not exist,但 sandbox 还是挂 - ❌ 关闭
UsePAM— 和 sandbox 无关 - ❌
--security-opt seccomp=unconfined— 这是 Docker 层的 seccomp,和 OpenSSH 内部的 seccomp-bpf 无关 - ✅ dropbear 替代 OpenSSH — dropbear 不使用 seccomp sandbox,完美兼容
最终方案:用 dropbear-bin 替代 openssh-server,在 entrypoint.sh 中自动安装和配置。
Q2: Mac 本地有一个同名废弃容器,和 NAS 容器混淆了
问题现象:Mac 上 docker ps 显示 sanguo_vnpy 运行 3 周,但容器内找不到回测服务。
根因:Mac 本地的 Docker Desktop 也运行了一个 sanguo_vnpy 容器(旧的 latest 镜像),和 NAS 上的 with-scripts 容器同名但完全不同。Mac 的 docker 命令操作的是本地 Docker,不是 NAS。
教训:检查远程 Docker 时必须通过 SSH 执行:
ssh admin@192.168.2.154 "/usr/local/bin/docker ps"
# 而不是本地的 docker ps
解决:清理 Mac 本地废弃容器 docker stop sanguo_vnpy && docker rm sanguo_vnpy。
Q3: 为什么 entrypoint.sh 里要 pip install 而不是写进镜像?
问题:vnpy_ctastrategy 和 vnpy_sqlite 没有写进 requirements.txt,而是在 entrypoint.sh 里每次启动时安装。
原因:
- 这两个包在构建基础镜像时可能版本不匹配
- 容器可写层的 pip 包在容器删除后会丢失,但
docker restart不会丢 - 灵活性:可以随时调整版本而不重建镜像
已缓解:entrypoint.sh 已移除 set -e,即使安装失败也不会导致容器退出,其他服务仍可正常启动。
改进方向(司马懿评审):将 vnpy_ctastrategy、vnpy_sqlite 加入 requirements-extra.txt,dropbear-bin 加入 Dockerfile apt 安装层,彻底消除网络依赖。
Q4: 为什么有 latest 和 with-scripts 两个镜像?
问题:Mac 本地 sanguo_vnpy:latest 和 NAS sanguo_vnpy:with-scripts 的区别。
说明:
latest:基础镜像,/app/scripts/里只有 deployment/utils/verify 工具脚本,没有backtest_service目录with-scripts:在latest基础上,将scripts/backtest-service/拷贝为/app/scripts/backtest_service/,使回测服务可以从镜像内启动
当前设计:回测服务代码通过 volume 挂载(bt-service → /app/scripts/backtest_service),镜像内是否有已不重要。但 with-scripts 镜像确保即使 volume 没挂载,容器内也有基础代码。
Q5: 为什么需要 --privileged 模式?
问题:--privileged 安全性较差,为什么不用 --security-opt seccomp=unconfined?
尝试过程:
- 先用
--security-opt seccomp=unconfined— 不够,OpenSSH 内部的 seccomp-bpf 不受 Docker seccomp profile 控制 - 改用
--privileged— 解决了所有问题
进一步测试(司马懿评审建议):尝试去掉 --privileged——结果失败。去掉后容器在 dropbear 配置阶段退出,进入重启循环。原因:entrypoint 中 sudo/apt-get 等操作需要完整权限能力。
风险:--privileged 给容器几乎完整的 host 权限。当前容器跑在内网 NAS 上,风险可接受。未来如需收紧,需先将 dropbear 安装写入镜像以避免 entrypoint 中的 sudo 操作。
Q6: 回测服务代码已统一为一份
说明:
/volume1/stock/sanguo_vnpy/bt-service/— 当前生效的,volume 挂载到容器内使用/volume1/stock/sanguo_vnpy/backtest-service-new/— 开发/备份目录/volume1/stock/sanguo_vnpy/scripts/backtest-service/— 镜像内置的旧版
已解决(2026-05-03):backtest-service-new/ 和 scripts/backtest-service/ 已打包归档到 archives/,NAS 上只保留 bt-service/ 一份。
Q7: 容器内 SSH 的 host keys 每次重启都会变,导致 known_hosts 报错
原因:host keys 在容器可写层,容器删除重建后会重新生成。
解决方案:
- 首次连接时用
-o StrictHostKeyChecking=no跳过验证 - 或将 host keys 持久化到 NAS volume(待实现)
Q8: 数据增量更新走 SMB 而非容器 API,有什么问题?
当前状态:Mac 端 cron 每交易日 15:30 触发 daily_update.sh → updater.py,通过 SMB 直接读写 NAS 上的 quant_trading.db。
风险:
- Mac 重启后 SMB 未自动挂载,更新会跳过
- SMB 读写大文件(1.4GB DB)偶尔有锁文件问题
- 数据写入绕过了 vnpy 框架的数据接口
待更新:赵云已出新的每日增量更新方案(daily_all_update.py),覆盖日线+15min。详见赵云的数据平台文档。
待改进:改为通过回测服务 API 触发数据更新,或直接在容器内跑 cron。
Q9: Docker 镜像构建时为什么 scripts 目录总是少文件?
历史问题(2026-04-14):Dockerfile 里 COPY scripts /app/scripts 拷贝的是本地仓库的 scripts/ 目录,而 NAS 上的 scripts/ 目录和本地不同步。
根因:代码仓库(gitee)和 NAS 上的文件不是同一份。Dockerfile 构建时用的是 NAS 上的文件,但 COPY 的路径是相对 Dockerfile 的。
教训:确保在正确的目录执行 docker build,且构建上下文中包含所有需要的文件。
Q10: 为什么 code-server 没有启用?
原因:Dockerfile 中注释掉了 code-server 安装(网络环境问题),entrypoint.sh 中已移除 code-server & 调用,避免静默失败污染日志。当前有 Jupyter Lab 足够。
10. 待改进项
| # | 问题 | 优先级 | 方案 |
|---|---|---|---|
| 1 | --privileged 安全风险 |
低 | 内网环境可接受,未来可降级 |
| 2 | SSH host keys 不持久 | 低 | 挂载 volume 到 /etc/dropbear/ |
| 3 | 数据更新走 SMB | 中 | 改为容器内 cron 或 API 触发 |
| 4 | NAS SMB 开机无自动挂载 | 中 | Mac 端配置 LaunchDaemon automount |
| 5 | DB 导入非全自动 | 中 | 编写导入脚本自动化 |
| 6 | 分钟线数据不完整 | 中 | 赵云补充分钟线数据导入 |
| 7 | — | ✅ 已确认数据实际更新到 2026-04-30,dbbaroverview 表未刷新但实际数据正常 | |
| 8 | pip 每次启动重装耗时 ~30s | 低 | 可接受,或写入镜像 |
| 9 | dropbear 安装需要 apt 联网 | 中 | 断网时容器无法启动,应写入镜像(司马懿评审问题1) |
| 10 | entrypoint pip 依赖网络 | 中 | 同上,应写入镜像 |
| 11 | — | ✅ 已清理归档(2026-05-03) |
11. 附录
11.1 回测服务代码结构(bt-service/)
bt-service/
├── main.py # FastAPI 应用入口
├── api.py # API 路由定义
├── executor.py # vnpy 回测执行器(核心)
├── models.py # Pydantic 数据模型
├── config.py # 配置管理
├── task_queue.py # 任务队列(线程池)
├── result_storage.py # 结果持久化
└── README.md # 服务说明文档
11.2 NAS 目录完整结构
/volume1/stock/sanguo_vnpy/
├── bt-service/ # 回测服务代码(volume 挂载,当前生效)
├── backtest-service-new/ # 回测服务代码(开发备份)
├── entrypoint.sh # 容器启动脚本(volume 挂载)
├── entrypoint.sh.backup # 旧版启动脚本备份
├── data/
│ ├── quant_trading.db # vnpy 交易数据库(1.4GB)
│ ├── quant_trading.db.bak # 备份
│ └── all_stocks.csv # 股票列表
├── docker/
│ ├── Dockerfile # 镜像构建文件
│ ├── entrypoint.sh # 镜像内置启动脚本
│ └── requirements/
│ ├── requirements-base.txt
│ └── requirements-extra.txt
├── scripts/
│ ├── backtest-service/ # 旧版回测服务(镜像内置)
│ ├── deployment/ # 部署脚本
│ ├── utils/ # 工具脚本
│ └── verify/ # 验证脚本
├── strategies/ # 策略代码
├── config/
│ ├── nginx/ # Nginx 配置(预留)
│ └── systemd/ # Systemd 配置(预留)
├── jiangwei-platform/ # 姜维平台脚本
├── pangtong-value/ # 庞统价值策略
├── zhangfei-technical/ # 张飞技术策略
├── vnpy_webtrader/ # Web Trader 项目
├── research/ # 研究资料
├── test/ # 测试代码
├── archives/ # 归档
├── backup/ # 备份
├── logs/ # 日志
└── README-NAS-DEPLOY.md # NAS 部署说明
11.3 关键环境变量
| 变量 | 值 | 说明 |
|---|---|---|
PYTHONUNBUFFERED |
1 | Python 输出不缓冲 |
PYTHONDONTWRITEBYTECODE |
1 | 不生成 .pyc |
DEBIAN_FRONTEND |
noninteractive | apt 非交互 |
TZ |
Asia/Shanghai | 时区 |
三国量化团队 · 姜维(平台总督)