# 小白复盘局域网 Docker 部署 本文以 Linux 服务器为目标,容器内外均使用 `8765` 端口,宿主机监听 `0.0.0.0:8765`。局域网用户通过 `http://服务器局域网IP:8765` 访问。 ## 1. 部署结构 ```text 局域网浏览器 | v 服务器 0.0.0.0:8765 | v xiaobai-review 容器 :8765 |-- /app 只读应用代码 `-- /app/data 宿主机 ./data 持久化挂载 ``` 账号、加密后的公共数据 Token、平台模型 API Key、生辰资料、行情快照和复盘数据均在 `data/review.db`。解密密钥来自 `.env` 中的 `APP_ENCRYPTION_KEY`。数据库与 密钥必须成对备份,任意一个丢失都无法恢复账号内的加密资料。 管理员私有的问师 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 ``` ### 使用 Gitea 更新程序(推荐) 代码仓库为: ```text http://192.168.200.36:3200/leefer/xiaobaifupan.git ``` 首次在服务器部署代码时,可以直接克隆到目标目录: ```bash sudo mkdir -p /opt/xiaobai-review sudo chown "$USER":"$USER" /opt/xiaobai-review git clone http://192.168.200.36:3200/leefer/xiaobaifupan.git /opt/xiaobai-review cd /opt/xiaobai-review ``` 私有仓库会提示输入 Gitea 用户名和密码或访问令牌。不要把密码写入仓库 URL、 `compose.yaml` 或脚本。然后把原 `.env` 与 `data/` 放回该目录;这两项已被 Git 忽略,后续拉取代码不会覆盖数据库与密钥。 如需部署管理员私有问师,通过 NAS 文件管理器将本地 `data/private-mentor-skills/` 复制到服务器项目的同名 `data` 目录,并保持目录仅由 部署账号和容器运行用户读取。该内容不会通过 Gitea 同步。 每次更新前先创建 SQLite 一致性备份,再拉取并重建容器: ```bash cd /opt/xiaobai-review docker compose exec -T xiaobai-review python -c "import sqlite3; s=sqlite3.connect('/app/data/review.db'); d=sqlite3.connect('/app/data/review-before-update.db'); s.backup(d); d.close(); s.close()" git pull --ff-only origin main docker compose up -d --build docker compose ps curl --fail http://127.0.0.1:8765/api/health ``` `docker compose up -d --build` 会原地替换应用容器,不删除宿主机的 `data` 目录。 数据库迁移会在新容器启动时自动执行。若 `git pull --ff-only` 提示本地代码有修改, 先用 `git status` 查明原因,不要用强制重置覆盖 `.env` 或 `data`。 ### 不使用 Git 时更新 重新上传代码后执行: ```bash docker compose down docker compose build --pull docker compose up -d ``` `docker compose down` 不会删除宿主机的 `data` 目录。不要使用带有手工删除 `data` 目录的清理命令。 ## 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,并限制可信来源。