Files
xiaobai-review/DOCKER_DEPLOY.md
T
2026-08-29 23:27:18 +08:00

274 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 小白复盘局域网 Docker 部署
本文以 Linux 服务器为目标,容器内外均使用 `8765` 端口,宿主机监听
`0.0.0.0:8765`。局域网用户通过 `http://服务器局域网IP:8765` 访问。
## 1. 部署结构
```text
局域网浏览器
|
v
服务器 0.0.0.0:8765
|
v
xiaobai-review 容器 :8765
|-- /app 只读应用代码
| `-- backend/features/heaven/assets/heaven_knowledge.json
| 镜像内 seed(不受 data 挂载遮盖)
`-- /app/data 宿主机 ./data 持久化挂载
|-- review.db
|-- iching_zh.json
`-- heaven_knowledge.json 优先读取;缺失时回退到上方 seed
```
账号、加密后的公共数据 Token、平台模型 API Key、生辰资料、行情快照和复盘数据均在
`data/review.db`。解密密钥来自 `.env` 中的 `APP_ENCRYPTION_KEY`。数据库与
密钥必须成对备份,任意一个丢失都无法恢复账号内的加密资料。
问天静态知识文件:
- `data/iching_zh.json``data/heaven_knowledge.json` 纳入 Git 与镜像构建;
`.dockerignore` 不排除这两个文件(只排除 `data/*.db``data/cache/` 等运行时产物)。
- Compose 把宿主机 `./data` 整目录挂到 `/app/data`,会遮盖镜像里同路径文件。
因此宿主机 `data/` 应保留上述两个 JSON;若只缺 `heaven_knowledge.json`
服务会回退读取镜像内
`backend/features/heaven/assets/heaven_knowledge.json`,解势仍可用。
- 持久化位置:正式环境以宿主机项目目录下的 `./data/heaven_knowledge.json` 为准;
补文件后无需改代码,重启容器即可加载。
管理员私有的问师 Skill 保存在宿主机 `data/private-mentor-skills/`。该目录随 `data`
挂载进入容器,但被 Git 与 Docker 构建上下文排除,不会进入 Gitea 或镜像。私有 Skill
只对管理员账号返回和开放调用,也会随本指南的 `data` 备份一起保存。
首个注册账号自动成为管理员。管理员在“系统管理”中配置全站共享行情、后台刷新、平台会员模型及手动会员;普通用户的“账号设置”用于个人资料、会员状态、修改密码和切换账号。后台行情更新不会主动刷新任何浏览器页面。
## 2. 服务器要求
- 64 位 Linux 服务器;
- Docker Engine 24 或更新版本;
- Docker Compose v2,命令形式为 `docker compose`
- 服务器可以访问 Tushare、已配置的 LLM 和实时聚合数据源;
- 局域网内没有其他服务占用 TCP `8765`
验证 Docker
```bash
docker --version
docker compose version
```
## 3. 迁移现有数据
迁移前先停止当前 Windows 服务,避免复制过程中 SQLite 继续写入。
然后在应用目录执行一次 WAL 检查点:
```powershell
python -c "import sqlite3; c=sqlite3.connect('data/review.db'); print(c.execute('PRAGMA wal_checkpoint(TRUNCATE)').fetchone()); c.close()"
```
结果第一项应为 `0`。必须迁移以下内容:
```text
data/
.env
Dockerfile
compose.yaml
其余程序文件
```
不要重新生成 `APP_ENCRYPTION_KEY`。部署已有数据库时,目标服务器 `.env` 中的
值必须与原服务器完全一致。
可以在项目目录生成迁移包:
```powershell
tar --exclude='__pycache__' --exclude='*.log' --exclude='data/cache' -czf ..\xiaobai-review.tar.gz .
scp ..\xiaobai-review.tar.gz 用户名@服务器IP:/tmp/
```
迁移包包含数据库和密钥,传输完成后应及时删除两端的压缩包。
## 4. 首次启动
在 Linux 服务器执行:
```bash
sudo mkdir -p /opt/xiaobai-review
sudo chown "$USER":"$USER" /opt/xiaobai-review
tar -xzf /tmp/xiaobai-review.tar.gz -C /opt/xiaobai-review
cd /opt/xiaobai-review
chmod 600 .env
sudo chown -R 10001:10001 data
docker compose config
docker compose build --pull
docker compose up -d
```
镜像使用 UID/GID `10001` 的非 root 用户运行,因此宿主机 `data` 目录必须允许
该用户写入。不要把整个应用目录设为可写。
检查运行状态:
```bash
docker compose ps
docker compose logs --tail=100 xiaobai-review
curl http://127.0.0.1:8765/api/health
docker inspect --format '{{.State.Health.Status}}' xiaobai-review
```
健康接口应返回类似内容:
```json
{"ok": true, "storage": "sqlite", "account_required": true}
```
随后在局域网电脑访问:
```text
http://服务器局域网IP:8765
```
## 5. 防火墙
Compose 已明确绑定 `0.0.0.0:8765`。服务器防火墙建议只允许实际局域网网段,
不要在路由器上把该端口映射到公网。
Ubuntu/UFW 示例,假设局域网为 `192.168.1.0/24`
```bash
sudo ufw allow from 192.168.1.0/24 to any port 8765 proto tcp
sudo ufw status
```
如果服务器位于其他网段,应替换为实际 CIDR。访问失败时同时检查云服务器安全组、
虚拟化平台防火墙和宿主机防火墙。
## 6. 日常管理
查看日志:
```bash
cd /opt/xiaobai-review
docker compose logs -f --tail=100 xiaobai-review
```
重启:
```bash
docker compose restart xiaobai-review
```
停止:
```bash
docker compose down
```
### 服务器本地目录更新与构建(日常推荐)
生产机 `192.168.200.11``/opt/1panel/docker/compose/xiaobaifupan` 自 2026-08-29HEL-235B
起已是受 Git 管理的工作目录,只跟踪 Gitea `main`(仓库
`http://192.168.200.36:3200/leefer/xiaobai-review.git`)。由于目录顶层归 root
`.git` 存放在部署账号家目录(外部 Git 目录方案):
```text
~/xiaobai-build/repos/xiaobai-review.git Git 元数据(分支/历史/索引)
/opt/1panel/docker/compose/xiaobaifupan 工作目录(程序文件本体)
~/xiaobai-build/update-from-main.sh 一键更新+构建入口
~/xiaobai-git 便捷查看(status/log/diff
```
日常更新只需要在服务器上执行一条命令:
```bash
~/xiaobai-build/update-from-main.sh # 更新到 main 并构建 main-<短号> 镜像
~/xiaobai-build/update-from-main.sh verify-tag main-a8732f5 # 部署前复核镜像与 main 一致
```
脚本在构建前强制完成五道校验,任一不符立即停止、不产出镜像:
1. `git fetch` 成功(连不上 Gitea 即停);
2. 必须在 `main` 分支(智能体不得用功能分支直接当正式线);
3. 工作区无未提交改动、无多余文件;
4. 只允许快进合并到 `origin/main`(分叉即停);main 新增/删除顶层文件时会给出
需管理员执行的精确清单(目录顶层归 root);
5. 构建后回读镜像 `org.opencontainers.image.revision`,与 `main` 提交不一致则删除镜像。
镜像 tag 固定为 `main-<提交短号7位>`(不带提交号的模糊 tag 一律禁止);每次构建在
`~/xiaobai-build/BUILD_LOG.tsv` 留痕。构建只产出镜像,不启动、不替换容器;换版与
回滚步骤见 `~/xiaobai-build/README.md`
`compose.yaml` 的镜像名与 revision 标签同样做了强校验:直接 `docker compose up -d --build`
会因缺少 `XIAOBAI_GIT_REV` / `XIAOBAI_GIT_SHORT` 变量而拒绝执行,避免再出现构建进
`latest` 的模糊版本。需要用 compose 时先 `export` 这两个变量(值以
`~/xiaobai-build/xiaobai-git rev-parse HEAD` 为准),或直接用上面的脚本。
### 智能体高级入口:Git 归档流式构建
有仓库检出、能免密 SSH 到部署机的智能体可以用 `tools/build_image.sh <提交号> <镜像tag>`
从任意明确提交流式构建(`git archive | ssh docker build`),tag 同样必须以
`-<提交短号7位>` 结尾,构建后回读 revision 校验并留痕。用于在服务器不便拉取时的
应急构建;日常正式线仍应走 `main`
### 历史方式(已废弃)
早期文档建议在服务器重新 `git clone` 一份或手工上传代码后 `docker compose up --build`
这两条路径已废弃:服务器上**只允许存在一个受管工作目录**(上述
`/opt/1panel/docker/compose/xiaobaifupan`),任何脱离 Git 校验的本地构建都会把
来源提交变成不可追溯状态,禁止使用。
## 7. 备份与恢复
最稳妥的备份方式是短暂停服后同时备份数据库目录和密钥:
```bash
cd /opt/xiaobai-review
docker compose stop xiaobai-review
tar -czf "xiaobai-backup-$(date +%Y%m%d-%H%M%S).tar.gz" data .env
docker compose start xiaobai-review
```
恢复时先停止容器,再恢复 `data` 和与其配套的 `.env`,修复权限后启动:
```bash
docker compose down
sudo chown -R 10001:10001 data
chmod 600 .env
docker compose up -d
```
## 8. 常见问题
### 容器反复重启
```bash
docker compose logs --tail=200 xiaobai-review
```
优先检查 `.env` 是否存在、`APP_ENCRYPTION_KEY` 是否为空,以及 `data` 是否可写。
### 提示账号加密数据无法解密
目标服务器使用了错误的 `APP_ENCRYPTION_KEY`。停止容器并恢复与数据库配套的
原始 `.env`,不要通过重置密钥绕过该错误。
### SQLite 显示只读或无法打开
```bash
sudo chown -R 10001:10001 /opt/xiaobai-review/data
sudo chmod -R u+rwX /opt/xiaobai-review/data
docker compose restart xiaobai-review
```
### 本机健康检查正常但其他电脑无法访问
确认 `docker compose ps` 显示 `0.0.0.0:8765->8765/tcp`,然后检查服务器防火墙和
客户端到服务器的网络路由。
## 9. 安全边界
当前部署使用局域网 HTTP,账号密码和会话只适合可信内网使用。不要直接将
`8765` 暴露到互联网。以后需要公网访问时,应在容器前增加 Caddy 或 Nginx
启用 HTTPS,并限制可信来源。