Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Quantmind Deploy

FSecurity

QuantMind 部署与运维 — 一键部署、快速部署、Docker 部署、数据库初始化、部署问题排查。在 QuantBot / Claude Code 中部署 QuantMind、排查部署失败、初始化数据库、检查服务健康、更新部署时使用。触发词:部署、一键部署、快速部署、部署失败、装不上、怎么部署、docker部署、部署问题、数据库初始化、服务起不来

1,703 stars
0 votes
0 copies
0 views
Added 10/5/2026
developmentpythongojavabashsqlreactnodefastapispringdocker

Works with

claude codecliapi

Security Analysis

F31/100
mediumUses curl or wget to download content
criticalAccesses sensitive system or user directories
criticalAccesses sensitive system or user directories
highCreates or modifies cron jobs for persistent execution
criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned 10/5/2026

$npx -y skills add qusong0627/QuantMind --skill quantmind-deploy --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Quantmind Deploy?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Quantmind Deploy
[![Security: F — Skills Directory](https://www.skillsdirectory.com/api/skills/qusong0627-quantmind-deploy/badge)](https://www.skillsdirectory.com/skills/qusong0627-quantmind-deploy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: quantmind-deploy
description: "QuantMind 部署与运维 — 一键部署、快速部署、Docker 部署、数据库初始化、部署问题排查。在 QuantBot / Claude Code 中部署 QuantMind、排查部署失败、初始化数据库、检查服务健康、更新部署时使用。触发词:部署、一键部署、快速部署、部署失败、装不上、怎么部署、docker部署、部署问题、数据库初始化、服务起不来"
---

> ⚙️ 本技能遵循公共运行环境契约(最高优先级,先于本文其余内容执行):
> 详见 [_shared/env-contract.md](../_shared/env-contract.md),执行前先读它。

# QuantMind 部署技能

QuantMind 部署运维完整指南。覆盖**部署前准备 → 一键/手动部署 → 部署后检查 → 问题排查 → 更新 → 云端训练**全流程。本技能针对 AI 编程助手编写,每步都给出可直接执行的命令与判断标准,避免"不知道下一步"卡壳。

## 0. 安装技能包(让 AI 帮你部署)

本技能包兼容**主流 AI 编程工具**(Claude Code / Codex / OpenCode / Trae / MarsCode 等),安装后 AI 能自动识别"部署/装不上"等意图并调用本技能指导部署。

### 方式一:Claude Code / QuantBot(原生 SKILL.md)

```bash
# 解压到 Claude Code 全局技能目录
unzip quantmind-operations-skill.zip -d ~/.claude/
# 验证
ls ~/.claude/skills/quantmind-deploy/SKILL.md
```

### 方式二:从项目仓库安装(任何工具)

```bash
# 项目根目录 skills/ 下即全部技能
cp -r /opt/quantmind/skills/* ~/.claude/skills/
```

### 方式三:其他主流 AI 工具(OpenCode / Codex / Trae / MarsCode 等)

各工具虽不原生识别 SKILL.md,但都读取 **AGENTS.md**(项目级指令)。把技能包要点导入即可:

```bash
# ① 通用做法:把 SKILL.md 内容并入 AGENTS.md
# 项目根创建/追加 AGENTS.md,把关键流程粘贴进去
cat ~/.claude/skills/quantmind-deploy/SKILL.md >> AGENTS.md

# ② OpenAI Codex
unzip quantmind-operations-skill.zip -d ~/.codex/
# Codex 读取 ~/.codex/AGENTS.md(把本技能要点放入)

# ③ OpenCode
unzip quantmind-operations-skill.zip -d ~/.config/opencode/
# 或在项目根 AGENTS.md 引用本技能要点

# ④ 腾讯 Trae / 字节 MarsCode
# 克隆仓库后把 SKILL.md 要点写入项目 AGENTS.md,AI 即可按流程部署
```

### 让 AI 部署

安装技能后,直接对 AI 助手说:

- "帮我部署 QuantMind" → AI 读取本技能,按"部署前准备→部署→检查"执行

- "部署不上,帮我排查" → AI 按"问题排查"诊断树逐项定位

- "一键部署" → AI 执行 `deploy/full-deploy.sh`

### 推荐编程工具(部署环境)

| 工具                        | 用途         | 说明                      |
| ------------------------- | ---------- | ----------------------- |
| **Claude Code**           | AI 编程/部署助手 | 原生支持 SKILL.md,装技能包即自动识别 |
| **OpenCode**              | AI 编程助手    | 开源,读 AGENTS.md          |
| **OpenAI Codex**          | AI 编程助手    | 读 \~/.codex/AGENTS.md   |
| **腾讯 Trae / 字节 MarsCode** | AI IDE     | 读项目 AGENTS.md           |
| **VS Code**               | 代码编辑       | 前端/后端调试                 |
| **Docker Desktop**        | 容器管理       | 本地调试用,服务器用 docker-ce    |
| **MobaXterm / Termius**   | SSH 终端     | 连服务器执行部署命令              |
| **Git**                   | 版本管理       | 拉取/更新代码                 |

## 架构总览

QuantMind 单机 Docker Compose 部署(`docker-compose.yml`),11+ 服务:

| 容器                       | 服务            | 端口        | 说明                          |
| ------------------------ | ------------- | --------- | --------------------------- |
| `quantmind-db`           | PostgreSQL 15 | 5432      | 主数据库                        |
| `quantmind-redis`        | Redis 7       | 6379      | 缓存/消息(DB 0-5 分配)            |
| `quantmind`              | 后端主服务         | 8000-8003 | api/engine/trade/stream 四合一 |
| `quantmind-celery`       | Celery Worker | —         | 异步任务(回测/同步/推理)              |
| `quantmind-celery-beat`  | Celery Beat   | —         | 定时调度                        |
| `quantmind-web`          | 前端 Web        | 80        | Nginx 托管 React 构建产物         |
| `quantmind-data-gateway` | 数据网关          | —         | 行情/资金流聚合                    |
| `quantmind-huntly`       | Huntly        | 8090      | RSS 新闻存储/阅读器                |
| `quantmind-rsshub`       | RSSHub        | 1200      | 通用网站订阅                      |
| `qwenpaw`                | QwenPaw       | 8088      | AI 代理(可选);**默认仅绑 127.0.0.1**,外部直连需 `QWENPAW_BIND=0.0.0.0` |
| `ib-gateway`             | IB Gateway    | 4001/4002 | 盈透网关(实盘/模拟,.env 配 IB_ACCOUNT/IB_PASSWORD) |

> **QwenPaw 外部访问**:`qwenpaw` 端口默认只绑 `127.0.0.1`(安全收敛口径)。前端 QuantBot 页面用 iframe 直连
> `http://<API网关主机>:8088/`,若在远端浏览器/Electron 打开需要在 `.env` 增加 `QWENPAW_BIND=0.0.0.0`,
> 然后 `docker compose up -d qwenpaw`(**改端口映射必须 recreate,`restart` 不生效**),并在云安全组放行 8088
> 且**限定来源 IP**(QwenPaw 为免登录模式)。仅容器内 `http://qwenpaw:8088` 互访则无需改动。

## 1. 部署前准备(重要,先做完再部署)

### 1.1 环境要求(多系统 + 硬件)

| 项目          | 要求                           | 说明                                                      |
| ----------- | ---------------------------- | ------------------------------------------------------- |
| **系统**      | Ubuntu 22.04 LTS 或 24.04 LTS | **部署脚本仅支持 Ubuntu 22.04+**,其他系统会被拒绝                      |
| **Windows** | Docker Desktop + WSL2 后端     | 在 WSL2 终端内执行 `docker compose`                           |
| **macOS**   | Docker Desktop 直接运行          | 兼容                                                      |
| **云服务器**    | 任意 Docker 环境                 | 单机即可                                                    |
| **CPU 架构**  | **仅 x86\_64 / AMD64**        | **ARM(aarch64)不支持**——微软 Qlib 框架仅发布 x86\_64,ARM 无法装 Qlib |
| **CPU**     | 4 核以上                        | 推荐 8 核(训练/回测耗 CPU)                                      |
| **内存**      | 16GB 以上(运行)                  | 模型训练推荐 **64GB+**,推理/回测 **32GB+**;内存不足会 OOM 训练卡死         |
| **磁盘**      | 100GB 以上可用                   | 数据 + 镜像 + 特征快照(\~15GB)+ 模型                              |

> ⚠️ 训练机建议 ≥64GB 内存;若只有 32GB,缩小时间窗/特征数避免 OOM。

### 1.2 网络检查(部署前必测)

国内服务器常需配置镜像源。部署脚本会自动选 Docker/PyPI/APT 镜像源,也可手动指定。

```bash
# 检查 DNS + 各仓库连通性(任一失败先解决再部署)
curl -fsSL --connect-timeout 5 https://gitee.com >/dev/null && echo "gitee OK" || echo "gitee FAIL"
curl -fsSL --connect-timeout 5 https://registry.npmmirror.com >/dev/null && echo "npm OK" || echo "npm FAIL"
curl -fsSL --connect-timeout 5 https://pypi.org >/dev/null && echo "pypi OK" || echo "pypi FAIL"
docker info >/dev/null 2>&1 && echo "docker OK" || echo "docker 未安装(部署脚本会装)"
```

**网络差时的应对**:

- 手动指定 Docker 镜像源:`QUANTMIND_DOCKER_MIRROR=https://你的加速域名 sudo -E bash deploy/full-deploy.sh`

- Docker 镜像源:`/etc/docker/daemon.json` 配置 `registry-mirrors`(阿里云/腾讯云镜像加速)

- PyPI 源:`PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/`(构建镜像时 `--build-arg`)

### 1.3 提前决定要填写的内容

部署脚本会**交互式**问你以下内容,提前准备好答案:

| 部署时问什么              | 示例答案                          | 说明                                |
| ------------------- | ----------------------------- | --------------------------------- |
| 服务器 IP              | `192.168.1.100` / `localhost` | 无公网 IP 用 localhost 或局域网 IP        |
| 选择镜像源               | 国内选阿里云/中科大                    | 网络差时自动选,也可 `QUANTMIND_MIRROR=` 指定 |
| 是否确认部署              | `y`                           | 确认后开始安装                           |
| (可选)QuantDB API Key | `qdb_xxx`                     | **部署后**在后台填,见 \[\[quantdb-sdk]]   |

### 1.4 部署前备份

```bash
# 若已有旧数据/旧部署,先备份
sudo cp -r /opt/quantmind/data /opt/quantmind/data.bak.$(date +%Y%m%d)
```

## 2. 一键部署(推荐)

```bash
# 完整一键部署:从 CDN 下载完整业务数据/模型/Qlib 数据 + 镜像包,恢复后开箱即用
curl -fsSL https://gitee.com/qusong0627/QuantMind/raw/master/deploy/full-deploy.sh | sudo bash

# 自定义 CDN / 分支 / 镜像加速
sudo QUANTMIND_OFFLINE_BASE_URL='https://cdn.example.com/quantmind-offline' \
     QUANTMIND_REF='master' \
     QUANTMIND_DOCKER_MIRROR='https://你的镜像加速域名' \
     bash deploy/full-deploy.sh
```

**部署 8 阶段**(详见 `docs/部署指南.md` 第四节):

1. 安装系统依赖与 Docker / Compose,配置镜像加速;
2. 从 CDN 下载离线包并 SHA-256 全量校验(支持断点续传 / 复用);
3. 导入 Docker 镜像(9 个;`rsshub` 部署时在线拉取);
4. 拉取代码(支持 Compose/Dockerfile 受控覆盖层);
5. 恢复业务数据、模型与 Qlib 数据;
6. 恢复 PostgreSQL 业务数据(已有数据默认保留);
7. 恢复 QwenPaw 持久化卷;
8. 构建启动全部服务并自动配置 QwenPaw 运行时。

## 3. 源码部署(已下线)

> 在线源码部署脚本 `deploy/deploy.sh` / `quick-deploy.sh` 已从仓库移除。请使用第 2 节「一键部署」(`deploy/full-deploy.sh`),或按第 4 节用 `docker compose` 手动部署。

## 4. 手动部署(源码)

```bash
sudo git clone https://gitee.com/qusong0627/QuantMind.git /opt/quantmind
cd /opt/quantmind
# 编写 .env:DB_PASSWORD / SECRET_KEY / JWT_SECRET_KEY / STORAGE_MODE=local(见 docs/部署指南.md)
sudo docker compose build quantmind
sudo docker compose up -d
```

详见 `docs/部署指南.md` 第五节「完全手动部署」。

## 5. 数据库初始化(关键)

服务启动时自动幂等重放 **`backend/shared/db_init.sql`**(含 users 等全部核心表):

- 容器内路径 `/app/backend/shared/db_init.sql`(由 `./backend:/app/backend` 挂载提供)

- 优先从 quantmind 容器执行 psql,失败则从 db 容器执行

- 若存在 `data/quantmind_init.sql` 则补充初始化数据

```bash
# 手动执行数据库初始化
docker exec quantmind bash -c "psql -h db -U quantmind -d quantmind -f /app/backend/shared/db_init.sql --quiet -v ON_ERROR_STOP=0"
```

**初始化后必须验证 users 表存在**(最常见部署失败点):

```bash
docker exec quantmind-db psql -U quantmind -d quantmind -c "\dt users"
# 期望看到 users 表;若不存在说明 db_init.sql 没跑成功
```

## 6. 部署后检查(按顺序,每步都过再继续)

### 6.1 容器健康

```bash
docker compose -f /opt/quantmind/docker-compose.yml ps
# 期望 quantmind/quantmind-celery/quantmind-celery-beat/quantmind-web/quantmind-db/quantmind-redis 都 Up
```

### 6.2 数据库 & Redis

```bash
docker exec quantmind-db pg_isready -U quantmind          # 期望 "accepting connections"
docker exec quantmind-redis redis-cli ping                # 期望 "PONG"
```

### 6.3 后端 API 健康

```bash
curl -s http://localhost:8000/api/v1/health
# 期望返回 {"status":"healthy", ...} 含 api/engine/trade/stream 四服务
```

### 6.4 登录验证(关键:验证 users 表 + 认证链路)

```bash
curl -s -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123","tenant_id":"default"}'
# 期望返回 access_token;若 401/500 → users 表问题(见排查)
```

### 6.5 前端访问

```bash
curl -s -I http://localhost | head -1   # 期望 200 OK
```

### 6.6 登录后台 + 配置数据源

1. 浏览器访问 `http://服务器IP`,用 admin 登录
2. 后台「数据管理」配置 **QuantDB API Key**(见 \[\[quantdb-sdk]])
3. 触发一次数据同步(见 \[\[quantmind-operations]] 第 3 节)

## 7. 更新部署

```bash
cd /opt/quantmind
# 一键更新脚本(同步代码 → 重建核心镜像 → 重启服务 → 导入数据库补丁 → 健康检查,不动数据库数据)
sudo bash deploy/update.sh
# 更新到指定分支或 tag
sudo bash deploy/update.sh --ref master
# 覆盖服务器上未提交的代码改动(谨慎,用 --force 而非 --force-sync)
sudo bash deploy/update.sh --force
# 纯代码改动,跳过镜像重建
sudo bash deploy/update.sh --no-build

# 手动更新
git pull origin master
docker compose build
docker compose up -d
```

### 7.1 update.sh 自动做了什么(客户升级说明)

| 步骤      | 行为                                                                                                                                                                               | 数据是否受影响                     |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| 1 拉代码   | `git fetch origin $REF`;分支走 `checkout -B`,tag 走 `checkout --detach`;有未提交改动且未加 `--force` 时终止,`--force` 时 `reset --hard` + `clean`(排除 `data/models/db/logs/user_pools_local/.env`) | 否                           |
| 2 重建后端  | `docker compose build quantmind`(`--no-build` 跳过)                                                                                                                                | 否                           |
| 3 重启服务  | `up -d --no-deps --force-recreate quantmind [celery-worker celery-beat]` + `up -d --remove-orphans`                                                                              | 否                           |
| 4 数据库升级 | 扫描并执行 `data/upgrade_*.sql`(经 db 容器 `psql`);**无去重/自动备份**,补丁需自身幂等。历史补丁 v1.0.1~v1.0.8 已合并进 `backend/shared/db_init.sql` 第 66 节 | 否(PG 数据在 `postgres-data` 卷) |
| 5 健康检查  | `curl http://127.0.0.1:8000/health`(30 次 × 2s),失败即终止                                                                                                                             | 否                           |

> ⚠️ 数据库结构以 `backend/shared/db_init.sql` 为准,服务启动时幂等重放:新库按第 1~65 节建全,存量库靠第 66 节(已合并原 `upgrade_v1.0.1~v1.0.8`)补列 / 补约束 / 订正数据。`data/upgrade_*.sql` 仅承接后续新补丁,每次 update 都会重跑一遍(无去重记录),必须用 `IF NOT EXISTS` 等自防重;打新补丁时在 `data/` 新增 `upgrade_vX.Y.Z.sql` 即可,不用改脚本。

> ⚠️ update.sh 只重建后端 `quantmind` 镜像,**不** `build web`/data-gateway/dashboard。前端或可选服务代码有改动时,需走离线包成品镜像或手动 `docker compose build` 对应服务。

### 7.2 版本展示与落后提交提示

- 后端 `/api/v1/system/version` 返回 `version` / `commit` / `branch` / `update`;管理后台右上角与「用户中心 → 设置」共用该接口。
- `deploy/update.sh` 写入 `backend/shared/version.json`(完整 HEAD SHA + `rev_count`,`.gitignore` 内);本地未走 update.sh 时接口回落 `dev`。
- 落后数来自 Gitea 分支 `release-index` 上的 `release-index.json`(维护端 `python scripts/publish_release_index.py --push` 生成)。禁止改回 Gitee/GitHub compare,禁止把计数文件提交进 `master`。

### 7.3 升级后验证

```bash
# 容器健康 + 版本号
curl -s http://localhost:8000/api/v1/system/version
# 登录(数据库补丁执行无碍)
curl -s -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123","tenant_id":"default"}'
```

## 8. 云端 GPU 训练(AutoDL)

**推荐把 AutoDL 当训练 Worker,不要在实例里装整套 QuantMind。** AutoDL Python 镜像一般不能嵌套 Docker,走 `exec_mode: native_python`。完整步骤以仓库文档为准:

- 操作手册:[docs/部署指南.md](../../docs/部署指南.md) 第十一节
- 节点初始化:[deploy/autodl/README.md](../../deploy/autodl/README.md)

模型训练可跑在 **AutoDL 远程 GPU 节点**(主节点 Docker 默认是 CPU 训练)。

### AutoDL 训练节点配置

```bash
# 列出训练节点(本地 Docker + AutoDL 远程 GPU)
curl -s -H "$AUTH" "$BASE/api/v1/admin/models/training-nodes"
# 测试节点连接(native_python 测 SSH + Python/GPU;ssh_docker 测 docker)
curl -s -X POST -H "$AUTH" -H "$CT" "$BASE/api/v1/admin/models/training-nodes/test" \
  -d '{"node_id":"autodl-rtx4090"}'
```

主节点 `config/training_nodes.yaml`(gitignore)示例:

```yaml
nodes:
  - id: autodl-rtx4090
    host: connect.xxx.seetacloud.com
    port: <控制台端口>
    user: root
    exec_mode: native_python
    work_dir: /root/workspace
    quantdb_dir: /root/autodl-fs/quantdb
```

`.env` 设 `TRAINING_MASTER_HOST=<协调机公网IP>`。AutoDL 上先跑 `deploy/autodl/setup-autodl-native.sh`。

### AutoDL 远程训练镜像(仅 ssh_docker)

仅当远端**已经**有 Docker + GPU 直通时才用:

```bash
docker build --build-arg TORCH_DEVICE=gpu -f docker/autodl/Dockerfile -t quantmind-train:latest .
bash scripts/setup/build-autodl-remote.sh
```

### 远程训练流程

1. **配节点**:`config/training_nodes.yaml`(含 SSH 凭据,不入库)
2. **测连接**:`training-nodes/test`
3. **启动训练**:`run-training` 选 `node_id=autodl-x`
4. **看状态**:`training-runs/{run_id}`;节点状态 `training-nodes/{node_id}/status`
5. **模型回传**:产物 rsync 回 `/data/training_jobs/{run_id}/` 并注册

实例关机后 SSH 端口会变,必须改 yaml 的 `port`。

## 8b. AutoDL 实例内原生部署(无 Docker 环境)

> 实战记录(2026-08-16,RTX 5090 实例)。AutoDL 实例是容器(PID1=bash),**宿主机未开嵌套容器权限**,Docker 完全不可用。若需在实例内跑完整 QuantMind 平台(而非仅作训练节点),走原生部署。

### 环境探测(部署前必做)

```bash
# Docker 可行性判定:缺 SYS_ADMIN 能力位 + unshare 被禁 = 装不了 Docker(rootless 也不行)
grep CapEff /proc/self/status                      # a80425fb 缺 0x200000 (SYS_ADMIN)
unshare --user --map-root-user true 2>&1           # Operation not permitted → 无 userns
ps -p 1 -o comm=                                    # bash(非 systemd,开机自启只能挂 .bashrc)
```

### 原生部署步骤(全部装系统盘,保存镜像才完整)

````bash
# 1. 系统依赖(Ubuntu 22.04 源自带 PG14/Redis6,版本够用)
apt-get install -y postgresql redis-server nginx git build-essential cmake swig libgomp1

# 2. Python 3.10(对齐官方镜像;AutoDL 自带 miniconda 是 py3.12,必须另建环境)
conda create -n qm python=3.10 pip
source activate qm

# 3. torch GPU 版(走阿里云 PyPI,实测 4MB/s;官方 pytorch.org 在 AutoDL 被 403)
pip install torch==2.9.1 -i https://mirrors.aliyun.com/pypi/simple/

# 4. 其余依赖(与 Dockerfile.oss 同清单,requirements/*.txt + quantdb-sdk + patch_qlib)
pip install -r requirements.txt -r requirements/production.txt -r requirements/ai.txt
pip install "quantdb-sdk==0.3.3" && python docker/patch_qlib.py

# 5. PG 初始化(实例内无 systemd,用 pg_ctlcluster 拉起)
pg_ctlcluster 14 main start
su - postgres -c "psql -c \"CREATE ROLE quantmind LOGIN PASSWORD 'quantmind2026';\""
su - postgres -c "psql -c 'CREATE DATABASE quantmind OWNER quantmind;'"
PGPASSWORD=quantmind2026 psql -h 127.0.0.1 -U quantmind -d quantmind -f backend/shared/db_init.sql

# 6. Redis:redis-server --daemonize yes --port 6379

# 7. 环境变量:导出对齐 docker-compose.yml 的 env(DB_HOST=127.0.0.1,STORAGE_ROOT=数据目录)

# 8. 启动后端(setsid 彻底脱离 SSH 会话,否则 SSH 断开进程被杀)
cd /root/QuantMind && setsid nohup bash qm-start.sh > data/logs/backend.log 2>&1 < /dev/null &

# 9. 前端:本地 npm run build:react 构建 dist-react(~29M),scp 到 /usr/share/nginx/html/
#    nginx 反代 /api/→127.0.0.1:8000、/ws/→127.0.0.1:8003;$connection_upgrade 变量是
#    docker-nginx 专属,原生 nginx 直接写 Connection "upgrade"

# 10. 开机自启(无 systemd):写 /etc/autodl.sh(AutoDL 官方开机钩子,PID1 boot.sh 会调用它)
#    内容:service cron start + 调用 /root/qm-autostart.sh(pg_ctlcluster + redis --daemonize + nginx + setsid 后端 + qwenpaw + huntly)
#    cron 看门狗兜底:apt install cron && service cron start && crontab -e 加 "* * * * * bash /root/qm-watchdog.sh"
#    ⚠️ .bashrc 自启无效——PID1 是 boot.sh,不经过交互式登录;实例重启后 cron 不自起,必须写进 autodl.sh

### QwenPaw 原生部署(无 Docker)
```bash
# 源码来源:本地 docker 容器 agentscope/qwenpaw:latest 里 /app 目录(含构建好的 console/dist)
# 打包:docker exec qwenpaw tar czf /tmp/qwenpaw-src.tgz src pyproject.toml setup.py  (~15MB,console 已在 src/qwenpaw/console/)
# 云端:
conda create -n qwenpaw python=3.11 pip -y          # 注意:conda 可能因网络重试失败但实际创建成功,用 ls envs/qwenpaw/bin 确认
/root/miniconda3/envs/qwenpaw/bin/pip install -e /root/QwenPaw -i https://mirrors.aliyun.com/pypi/simple/
/root/miniconda3/envs/qwenpaw/bin/pip install asyncpg redis psycopg2-binary -i https://mirrors.aliyun.com/pypi/simple/
# 环境变量对齐 docker-compose qwenpaw 段:PYTHONPATH=/app + /app 下符号链接到 QuantMind(backend/config/scripts/working/models/logs/db)
#   已补 /etc/hosts: db→127.0.0.1、redis→127.0.0.1、qwenpaw→127.0.0.1、copaw→127.0.0.1
qwenpaw init --defaults --accept-security            # 生成 /app/working/config.json
qwenpaw app --host 0.0.0.0 --port 8088               # 启动(用 /root/qwenpaw-start.sh 带启动锁)
# 后端连 QwenPaw:.env.sh 加 QWENPAW_BASE_URL=http://127.0.0.1:8088,重启后端
# (COPAW_BASE_URL 为 Copaw 旧名遗留,代码已不读取,勿再配置)
# 前端访问:/api/v1/qwenpaw-ui/ 代理(无需 8088 直接暴露)
````

### Huntly 原生部署(无 Docker)

````bash
# 源码来源:本地 docker cp quantmind-huntly:/app/server.jar(~121MB,scp 约 20 分钟)
apt-get install -y default-jre-headless               # JRE 11 即可
java -Xms128m -Xmx1024m -Duser.timezone=GMT+08 -jar server.jar \
  --spring.profiles.active=default --server.port=8090 \
  --huntly.dataDir=/root/huntly/data/ --huntly.luceneDir=/root/huntly/data/lucene
# ⚠️ 首次启动自动建用户 changeme(HUNTLY_DEFAULT_USERNAME/PASSWORD 只在首次生效,之后改环境变量无效)
#    要改账号:sqlite3 db.sqlite "UPDATE users SET username='admin', password='<bcrypt>' WHERE username='changeme'"
#    密码是 bcrypt(10),用 python bcrypt.hashpw(b"admin123", bcrypt.gensalt(10))
# 后端连 Huntly:.env.sh 里 HUNTLY_USERNAME/HUNTLY_PASSWORD 改对后重启后端,news/health 应返回 up
# ⚠️ 8090 不在 AutoDL 公网映射(只有 6006/6008 映射),前端「后台」链接打不开:
#    方案 A(已落地):后端 /api/v1/news/huntly-ui/ 做 SPA 子路径代理(见下方「Huntly UI 代理」)——
#    HTML 路径重写 + JS 拦截脚本重写 fetch/XHR/WebSocket/EventSource 的 /api/ → 代理路径
#    前端资讯页「后台」按钮指向 /api/v1/news/huntly-ui/(SERVICE_ENDPOINTS.USER_SERVICE 拼接),无需 8090 公网暴露
#    方案 B(备用):nginx 单独 server 块 listen 6008 反代 127.0.0.1:8090(6008 映射到公网 443,前端 6006 映射 8443)

### Huntly UI 代理(SPA 子路径代理模式,news.py 已实现)
```bash
# 访问入口:https://<实例ID>.westd.seetacloud.com:8443/api/v1/news/huntly-ui/
# 登录:admin / admin123(Huntly 自己的账号体系,与 QuantMind 后端账号无关)
````

SPA 子路径代理必须做对四件事,缺一即部分功能失灵(实战踩坑记录):

1. **HTML 路径重写**:`src="/static/` → `src="/api/v1/news/huntly-ui/static/`、favicon/manifest 同理
2. **JS 拦截脚本注入** **`<head>`**:重写 `fetch`/`XMLHttpRequest.open`/`WebSocket` 的 `/api/` 前缀 → 代理路径
   (EventSource 构造也传 `/api/...` 字符串,走 fetch 重写不够,Huntly 用的是 `new EventSource("/api/...")`,需要把 EventSource 也包一层或确认其 URL 已被拦截;当前实现已覆盖)
3. **API 路由声明顺序**:FastAPI 按声明顺序匹配,`@router.api_route("/huntly-ui/api/{path:path}")` 必须声明在
   `@router.get("/huntly-ui/{path:path}")`(静态)**之前**,否则 GET 会被静态路由吞掉 → 不带鉴权转发 → 405/401
4. **Set-Cookie 透传**:Huntly 是 HttpOnly cookie 会话(`auth_token=...; Path=/; HttpOnly`),前端 JS 里根本不存 token。
   代理响应必须透传 `set-cookie` 头,浏览器才会把 cookie 存在 QuantMind origin 下;转发时后端 `_ensure_session()`
   的全局 JWT 兜底(带 Authorization + Cookie 双头)保证登录前/后 API 都通

```
```

### AutoDL 原生部署踩坑清单

| 坑                              | 现象                                                                                                                                                                                 | 解法                                                                                                                                                           | <br />                             | <br />                                                                                                                                                                                                                                                |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Docker 装不上**                 | unshare/mount 全被拒                                                                                                                                                                  | 放弃 docker,原生部署(本表)                                                                                                                                           | <br />                             | <br />                                                                                                                                                                                                                                                |
| **/.dockerenv 触发容器重定向**        | AutoDL 实例**本身就是容器**(存在 /.dockerenv),`config.py` 检测到后把 REDIS\_HOST 强制改成 `quantmind-redis` → 原生部署无此 DNS,登录卡 \~24s DNS 超时                                                             | 把代码里所有 quantmind-\* 容器名全部写入 /etc/hosts → 127.0.0.1(\`grep -rhoE 'quantmind-\[a-z0-9\_-]+' backend --include='\*.py'                                          | sort -u\` 枚举,\~22 个);改完重启后端登录 0.3s | <br />                                                                                                                                                                                                                                                |
| **外网代码源全废**                    | GitHub 0-25KB/s、Gitee 613B/s、ghproxy 全超时、ACR 426B/s                                                                                                                                | 代码走**本地打包 scp**(瘦身后 \~16MB);依赖走**阿里云 PyPI**(4MB/s 唯一快源)                                                                                                      | <br />                             | <br />                                                                                                                                                                                                                                                |
| **SSH 直传限速**                   | \~100KB/s(30MB 传 5 分钟)                                                                                                                                                             | ①砍体积:exclude 掉 scenarios/fonts/torch\_wheels/rd-agent/bridge-windows 等大目录 ②并行传多个小包                                                                           | <br />                             | <br />                                                                                                                                                                                                                                                |
| **tar exclude 误伤**             | `--exclude='models'` 把 `backend/services/*/models` 全部剔除 → 四服务 ModuleNotFoundError 崩 5 次                                                                                            | 排除用精确路径;传完必须 `find backend -type d -name models` 对比本地远端                                                                                                      | <br />                             | <br />                                                                                                                                                                                                                                                |
| **pkill 断 SSH**                | pkill 模式匹配到 SSH 会话自身命令 → 连接断开(exit 255/144)                                                                                                                                        | 用 `pkill -f 'main_oss[.]py'` 正则字符类防自匹配;启动用 `setsid nohup ... < /dev/null`                                                                                    | <br />                             | <br />                                                                                                                                                                                                                                                |
| **nohup 目录未建**                 | 日志目录不存在导致启动静默失败                                                                                                                                                                    | 启动脚本里先 mkdir -p 所有数据/日志目录                                                                                                                                    | <br />                             | <br />                                                                                                                                                                                                                                                |
| **conda py312 不兼容**            | qlib 等依赖锁 py3.10                                                                                                                                                                   | 必须 `conda create -n qm python=3.10`                                                                                                                          | <br />                             | <br />                                                                                                                                                                                                                                                |
| **python 脚本生搬硬套**              | 用 `python3` 而非 conda 环境 python                                                                                                                                                     | 所有启动/验证用 `/root/miniconda3/envs/qm/bin/python`                                                                                                               | <br />                             | <br />                                                                                                                                                                                                                                                |
| **无 systemd**                  | systemctl 是摆设                                                                                                                                                                      | PG 用 pg\_ctlcluster、Redis 用 --daemonize、自启挂 /etc/autodl.sh(非 .bashrc);`apt install cron` 后还要 `service cron start` 并写进 /etc/autodl.sh(实例重启后 cron 不会自起,看门狗就废了) | <br />                             | <br />                                                                                                                                                                                                                                                |
| **看门狗 pgrep 失灵**               | main\_oss 的 uvicorn worker 经 multiprocessing.spawn 后 cmdline 被重写为 `spawn_main`(不含 main\_oss 字样)且 PPID=1,`pgrep -f main_oss` 永远匹配不到 → 看门狗每分钟误判重复拉起                                  | 看门狗按**端口监听**判断(\`ss -tln                                                                                                                                     | grep ":8000 "\`),不能用 pgrep -f      | <br />                                                                                                                                                                                                                                                |
| **两代进程混居**                     | 杀进程时 pkill 模式没匹配到主进程(如 `pkill -f main_oss[.]py` 匹配不到、`envs/qm` 匹配不到主进程)→ 旧 worker 占着端口,新启动的主进程端口绑定失败,日志刷 "crashed too many times (5/5)" 死循环,health 却显示 healthy(响应的是没人管的旧孤儿 worker) | ①清场用 \`ps -eo pid,cmd                                                                                                                                        | grep -E "main\_oss                 | envs/qm"  ` 枚举出 PID 逐个 kill -9(避免 pkill 自匹配)——**必须把 spawn_main 孤儿也杀掉**(它们的 cmdline 不含 main_oss,`ps  ` 里只有 spawn_main/resource_tracker 字样)②qm-start.sh 加**启动锁**(/tmp/qm-start.lock + trap EXIT 释放)防重复启动 ③验证:`ps`里`backend/main\_oss\` 恰好 1 个进程且四端口由它监听 |
| **Huntly UI 代理 401/405**       | GET /huntly-ui/api/\* 经代理全 401/500——FastAPI 路由声明顺序问题:静态 `/{path:path}` 先于 api\_route 声明,GET 被静态路由吞掉不带鉴权转发                                                                          | api\_route 必须声明在静态路由之前(见「Huntly UI 代理」);Set-Cookie 必须透传(Huntly 是 HttpOnly cookie 会话)                                                                         | <br />                             | <br />                                                                                                                                                                                                                                                |
| **qm-start.sh 路径写错**           | cd /root/QuantMind 后 `bash qm-start.sh` 报 No such file——脚本在 /root/ 不在仓库里                                                                                                           | 用绝对路径 `bash /root/qm-start.sh`                                                                                                                               | <br />                             | <br />                                                                                                                                                                                                                                                |
| **nginx $connection\_upgrade** | docker-nginx 专属变量,原生 nginx 配置报错/ws 不通                                                                                                                                              | websocket 反代直接写 `Connection "upgrade"`                                                                                                                       | <br />                             | <br />                                                                                                                                                                                                                                                |
| **AutoDL 端口映射**                | 只有 6006/6008 映射到公网(https\://<实例ID>.westd.seetacloud.com:8443/443),8000-8003 不映射                                                                                                    | nginx 额外 listen 6006(80 默认 server 的同一 server 块加 listen),对外访问走 8443                                                                                           | <br />                             | <br />                                                                                                                                                                                                                                                |
| **修改需重启才生效**                   | 改 /etc/hosts、.env 后旧进程还在                                                                                                                                                           | pkill(防自匹配)→ 重跑 qm-start.sh → 验证四端口 health + 登录                                                                                                              | <br />                             | <br />                                                                                                                                                                                                                                                |

### 部署后验证(AutoDL 原生)

```bash
for p in 8000 8001 8002 8003; do curl -s http://127.0.0.1:$p/health; done   # 四服务 healthy
time curl -s -X POST http://127.0.0.1:8000/api/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin123","tenant_id":"default"}'      # 返回 access_token 且 <1s
#   若 >20s 必是 /.dockerenv 陷阱(见踩坑清单第 2 条)
/root/miniconda3/envs/qm/bin/python -c "import torch; print(torch.cuda.get_device_name(0))"

# 外网访问(AutoDL 控制台「自定义服务」把 6006 映射成公网 8443 后):
curl -skI https://<实例ID>.westd.seetacloud.com:8443/ | head -1               # 前端 200
curl -sk -X POST https://<实例ID>.westd.seetacloud.com:8443/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin123","tenant_id":"default"}'      # 公网登录链路 200
```

## 9. 问题排查(诊断树,按顺序走)

### 9.1 先看这 3 条命令的输出(快速定位)

```bash
# 1. 容器状态(谁没起来)
docker compose -f /opt/quantmind/docker-compose.yml ps

# 2. 后端日志(报什么错)
docker compose -f /opt/quantmind/docker-compose.yml logs --tail=100 quantmind

# 3. 数据库连接
docker exec quantmind-db pg_isready -U quantmind
```

### 9.2 诊断树

```
部署后不能访问?
├─ curl localhost:8000/api/v1/health 失败
│   ├─ 容器没起来 → docker compose ps 看状态 → docker compose logs quantmind 看报错
│   ├─ 端口被占 → netstat -tlnp | grep 8000 → 释放冲突端口
│   └─ 数据库连不上 → docker exec quantmind-db pg_isready → 重启 db 容器
├─ health OK 但登录失败(401/500)
│   ├─ users 表不存在 → docker exec quantmind-db psql -U quantmind -d quantmind -c "\dt users"
│   │     → 无表则手动执行 db_init.sql(见第 5 节)
│   └─ SECRET_KEY 不一致 → 检查 .env 的 JWT_SECRET_KEY,重启后端
├─ 登录成功但前端打不开
│   ├─ curl -s -I http://localhost 失败 → nginx -t → systemctl restart nginx
│   ├─ PM2 没起 → pm2 status → pm2 restart quantmind-web
│   └─ 前端构建问题 → cd /opt/quantmind/electron && npm install && npm run dashboard:build
└─ 都正常但页面报"数据缺失"
    ├─ 未配 QuantDB API Key → 后台「数据管理」填 Key(见 [[quantdb-sdk]])
    └─ 未同步数据 → [[quantmind-operations]] 第 3 节触发同步
```

### 9.3 常见问题速查表

| 现象                      | 原因               | 处理                                                       |
| ----------------------- | ---------------- | -------------------------------------------------------- |
| **用户表不存在 / 登录失败**       | db\_init.sql 未执行 | 手动执行 db\_init.sql(见第 5 节);确认 `\dt users`                 |
| **Docker Compose 版本过低** | 需 v2.19+         | `docker compose version`,装 docker-compose-plugin         |
| **镜像拉取慢/失败**            | 网络源              | 脚本自动选 Docker/PyPI/APT 镜像源,可手动 `--build-arg` 指定           |
| **torch 安装失败**          | GPU/CPU 兼容       | Dockerfile 默认 `TORCH_DEVICE=auto`(构建期动态探测),可强制 `cpu/gpu/skip`;实际形态见镜像 `/etc/quantmind/torch-device` |
| **容器起不来**               | 端口冲突 / 配置        | `docker compose logs quantmind` 看日志                      |
| **数据库连接失败**             | PG 未就绪           | `docker exec quantmind-db pg_isready -U quantmind`       |
| **前端 502**              | Nginx/PM2        | `nginx -t` + `pm2 status` + `pm2 restart quantmind-web`  |
| **quantdb-sdk 安装失败**    | 版本兼容             | Dockerfile 用 `quantdb-sdk==0.3.3`,换源重装                   |
| **北向/南向无数据**            | 未同步              | 跑 `quantdb_north_sync` / `quanthk_south_sync`            |
| **GPU 训练不生效**           | 未配 AutoDL 节点     | `training-nodes/config` 配置后选 node\_id                    |
| **AutoDL 节点连不上**        | SSH 配置错          | `training-nodes/test` 诊断 SSH/docker                      |

### 9.4 AI 助手部署常见坑(给编程 AI 的提示)

| AI 常犯错误             | 正确做法                                       | <br />                     |
| ------------------- | ------------------------------------------ | -------------------------- |
| 跳过交互式确认             | `full-deploy.sh` 从 CDN 下载并恢复,非交互式(`curl ... \| sudo bash` 即可)        | <br />                     |
| 忽略系统版本              | 必须先 `check_system`(仅 Ubuntu 22.04+)        | <br />                     |
| 不检查 users 表         | 部署后必查 `\dt users`,这是登录失败主因                 | <br />                     |
| 直接 `docker-compose` | 新版用 `docker compose`(带空格)                  | <br />                     |
| 忘配 QuantDB Key      | 部署完成≠能用,还需在后台填 API Key + 同步数据              | <br />                     |
| 端口冲突硬上              | 先 `netstat -tlnp` 看占用,改 compose 端口         | <br />                     |
| 忘重启容器               | 改 `.env`/代码后要 `docker compose restart` 才生效 | <br />                     |
| 直接用 gitee master    | 生产固定 `v1.9.0-beta` tag,可复现                 | <br />                     |

## 数据目录(持久化)

```
/opt/quantmind/data/
├── postgres/       # 数据库数据
├── redis/          # Redis 数据
├── quantdb/        # QuantDB A股 parquet
├── quantus/        # 美股 parquet
├── quanthk/        # 港股 parquet
├── quantbc/        # 区块链 parquet
├── quantfutures/   # 期货 parquet
├── logs/           # 日志
└── models/         # 模型文件
```

## 相关技能

- **\[\[quantmind-operations]]** — 部署后数据同步、模型训练、推理

- **\[\[quantdb-sdk]]** — QuantDB 数据源配置(API Key)

- **\[\[simulation-trading]]** — 部署后模拟盘验证

Attribution

qusong0627qusong0627
View sourceSee grades on GitHubMore from qusong0627 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Clean Code

Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

304955 votes

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

286712 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Writing Plans

Use when you have a spec or requirements for a multi-step task, before touching code

2927051 votes
View all in development →