Files
BlueArchiveToolkit/docs/guides/deployment.md
T
2026-07-14 00:10:39 +08:00

425 lines
15 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.
# 部署指南
## 架构概览
BlueArchive Toolkit 的部署文档分为当前可用模式和目标模式:
1. **本地开发模式**:代码在本地,连接本地或远程数据库。
2. **官方资源同步生产任务**:当前可用,运行 Rust `bat --watch`
3. **完整单机/分布式部署**:尚未提供。API Server、数据库迁移和 Web 未实现前,不把它作为可执行部署方案。
---
## 模式 1:本地开发 + 远程数据库
适用场景:本地开发,数据库部署在有公网 IP 的远程服务器
### 步骤
#### 1. 在远程服务器上部署数据库
```bash
# SSH 登录到服务器
ssh user@your.server.com
# 创建部署目录
mkdir -p ~/bat/deployments
cd ~/bat/deployments
# 上传配置文件(在本地执行)
scp -r deployments/* user@your.server.com:~/bat/deployments/
# 配置环境变量
cp .env.example .env
nano .env # 设置强密码
# 启动数据库
docker compose -f docker-compose.remote-db.yml up -d
# 查看状态
docker compose -f docker-compose.remote-db.yml ps
```
#### 2. 配置防火墙
```bash
# 开放 PostgreSQL 端口
sudo ufw allow 5432/tcp
# 开放 Redis 端口
sudo ufw allow 6379/tcp
# 查看状态
sudo ufw status
```
#### 3. 本地连接配置
在本地项目根目录创建 `.env`
```env
DB_HOST=your.server.ip.address
DB_PORT=5432
DB_USER=bat_user
DB_PASSWORD=your_secure_password
DB_NAME=bluearchive_toolkit
REDIS_HOST=your.server.ip.address
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password
```
#### 4. 测试连接
```bash
# 测试 PostgreSQL 连接
psql -h your.server.ip.address -U bat_user -d bluearchive_toolkit
# 测试 Redis 连接
redis-cli -h your.server.ip.address -p 6379 -a your_redis_password ping
```
---
## 模式 2:本地数据库(开发)
适用场景:完全本地开发,不需要远程服务器
```bash
# 启动本地数据库
docker compose -f deployments/docker-compose.dev.yml --profile local-db up -d
# 配置 .env
DB_HOST=localhost
DB_PORT=5432
REDIS_HOST=localhost
REDIS_PORT=6379
```
---
## 模式 3:官方资源同步生产任务
当前可部署的生产任务是 Rust 官方资源同步 binary。API Server 和 Web 尚未实现,不能按完整服务端产品部署。
### 构建 release binary
```bash
cargo build --release -p bat-infrastructure --bin bat
```
产物:
```text
target/release/bat
```
生产不直接从 Git 工作区运行 binary。推荐把每次发布放进独立 release 目录,再用稳定 symlink 暴露当前版本:
```text
/opt/bluearchive-toolkit/releases/<version-or-git-sha>/bat
/opt/bluearchive-toolkit/bin/bat -> /opt/bluearchive-toolkit/releases/<version-or-git-sha>/bat
```
示例安装命令:
```bash
VERSION="$(git rev-parse --short HEAD)"
sudo install -d -o root -g root -m 0755 \
/opt/bluearchive-toolkit/releases/"${VERSION}" \
/opt/bluearchive-toolkit/bin
sudo install -o root -g root -m 0755 \
target/release/bat \
/opt/bluearchive-toolkit/releases/"${VERSION}"/bat
sudo ln -sfn \
/opt/bluearchive-toolkit/releases/"${VERSION}"/bat \
/opt/bluearchive-toolkit/bin/bat
/opt/bluearchive-toolkit/bin/bat --help
```
### 用户和目录
生产建议使用固定系统用户运行,不使用 root 长期运行同步进程:
```bash
getent group bat >/dev/null || sudo groupadd --system bat
id -u bat >/dev/null 2>&1 || sudo useradd --system \
--gid bat \
--home-dir /var/lib/bluearchive-toolkit \
--shell /usr/sbin/nologin \
bat
```
如果用户或组已存在,保留现有对象即可。推荐目录:
```text
/opt/bluearchive-toolkit/ # root 拥有,存 release binary 和当前 symlink
/etc/bluearchive-toolkit/ # root 拥有,存 service 配置
/var/lib/bluearchive-toolkit/official/ # bat 拥有,官方资源和同步状态
/var/lib/bluearchive-toolkit/daemon-state/ # bat 拥有,仅用于 standalone --daemon 持久状态
/run/bluearchive-toolkit/ # systemd 创建,运行期状态
/var/log/bluearchive-toolkit/ # systemd 创建,当前推荐用 journald
```
创建目录:
```bash
sudo install -d -o root -g root -m 0755 /etc/bluearchive-toolkit
sudo install -d -o bat -g bat -m 0750 \
/var/lib/bluearchive-toolkit \
/var/lib/bluearchive-toolkit/official \
/var/lib/bluearchive-toolkit/daemon-state
```
`/var/lib/bluearchive-toolkit/official/` 会保存:
- `current`:指向当前可读 release 的 symlink
- `versions/<id>/official-sync-snapshot.json`
- `versions/<id>/official-download-manifest.json`
- `versions/<id>/...` 下载得到的官方资源文件
- `.staging/<id>`:下载和校验中的临时 release
- `official-bootstrap-cache.json`
- `.official-sync.lock`
不要把输出目录设为:
- 已安装游戏客户端目录
- 官方启动器安装目录
- 开发机现有资源目录,例如 `/home/wanye/D/BlueArchive`
- Git 工作区目录
### 首次 dry-run
```bash
sudo -u bat /opt/bluearchive-toolkit/bin/bat \
--auto-discover \
--output /var/lib/bluearchive-toolkit/official \
--dry-run \
--no-progress
```
### 推荐模式:systemd 托管 `--watch`
生产推荐让 systemd 直接托管前台 `--watch` 进程,而不是在 systemd 里再启动 `--daemon`。原因:
- systemd 能直接追踪主进程、退出码、重启次数和 stop 信号。
- 日志进入 journald,用 `journalctl` 管理,不依赖 `bat-daemon.log`
- Rust 内部已经负责 1 小时间隔、北京时间固定强制刷新和失败快速重试,systemd 不需要 timer。
- `bat --daemon` 的 Unix socket RPC 适合没有进程管理器的 shell/container 场景;systemd 场景下用 `systemctl``journalctl``bat verify/doctor` 运维即可。
安装 unit 和可选环境文件:
```bash
sudo install -o root -g root -m 0644 \
deployments/systemd/bluearchive-toolkit-official-sync.service \
/etc/systemd/system/bluearchive-toolkit-official-sync.service
sudo install -o root -g root -m 0644 \
deployments/systemd/official-sync.env.example \
/etc/bluearchive-toolkit/official-sync.env
sudo systemctl daemon-reload
sudo systemctl enable --now bluearchive-toolkit-official-sync.service
```
检查状态和日志:
```bash
systemctl status bluearchive-toolkit-official-sync.service
journalctl -u bluearchive-toolkit-official-sync.service -f
sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor \
--output /var/lib/bluearchive-toolkit/official \
--state-dir /run/bluearchive-toolkit
```
`--watch` 是 Rust 内部持久检查模式,正常情况下默认每 1 小时执行一次检查,并且每天北京时间(UTC+8)`03:00``16:00``18:00` 会强制执行一次自动刷新。固定时间刷新会中断普通 interval 的 sleep,该轮注入 `force=true`;如果失败,会按失败重试周期继续重试。远端和本地一致时默认静默;有远端变化或本地文件损坏时自动下载或 repair,并输出人类可读摘要。下载、发现或校验失败时默认 60 秒后重试,可显式加 `BAT_ERROR_RETRY=60s` 或调整 service `ExecStart`。默认平台是 `Windows,Android`,无需显式传 `--platforms`;需要覆盖时用 systemd drop-in 重写 `ExecStart`。默认资源目录是 `./bat-resources`,生产 service 显式使用 `/var/lib/bluearchive-toolkit/official`。生产读取方应读取 `/var/lib/bluearchive-toolkit/official/current`;同步中的文件只会进入 `.staging/<id>`,校验完成后才发布为 `versions/<id>` 并切换 `current`
### 可选模式:CLI 自托管 `--daemon`
不使用 systemd 时,可以直接后台运行。生产中不要使用默认 `/tmp/bat-pid`,建议使用持久状态目录,这样 `bat-daemon.log``bat-events.jsonl` 不会随 reboot 或 tmp 清理丢失:
```bash
sudo -u bat /opt/bluearchive-toolkit/bin/bat \
--auto-discover \
--output /var/lib/bluearchive-toolkit/official \
--state-dir /var/lib/bluearchive-toolkit/daemon-state \
--daemon
sudo -u bat /opt/bluearchive-toolkit/bin/bat status --state-dir /var/lib/bluearchive-toolkit/daemon-state
sudo -u bat /opt/bluearchive-toolkit/bin/bat logs --state-dir /var/lib/bluearchive-toolkit/daemon-state --tail 200
sudo -u bat /opt/bluearchive-toolkit/bin/bat restart --state-dir /var/lib/bluearchive-toolkit/daemon-state
sudo -u bat /opt/bluearchive-toolkit/bin/bat reload --state-dir /var/lib/bluearchive-toolkit/daemon-state
sudo -u bat /opt/bluearchive-toolkit/bin/bat stop --state-dir /var/lib/bluearchive-toolkit/daemon-state
```
`--daemon` 会在 `--state-dir` 下创建 `bat.sock``bat.pid``bat-status.json``bat-daemon.log``bat-events.jsonl` 和短生命周期的 `bat-control.lock``bat.sock` 是 Unix socket JSON-RPC 控制通道;`status``stop``logs``reload` 和默认形态的 `refresh` 会优先连接 live daemon。PID、状态和日志文件保留为快照、诊断和 socket 不可用时的兼容路径;`bat-events.jsonl` 是带轮转的结构化 JSONL 事件日志;`bat-status.json` 会暴露最后成功时间、下次检查时间、最后错误摘要和当前下载进度;`bat-control.lock` 串行化控制命令,并能在 stale/corrupt 时由下一次控制命令或 `clean-stable` 恢复。`reload` 默认不会重启进程,而是让 watch 循环重新自动发现并强制刷新:空闲睡眠时立即唤醒,正在同步时排队到当前轮结束后执行;需要替换启动参数或 binary 时用 `restart`
不要同时运行 systemd `--watch` 和 standalone `--daemon` 指向同一个 `--output`。二者都会被资源锁和 live daemon 互斥保护,但生产运维上应保持单一 owner。
### 日志和状态路径
systemd 模式:
- 进程日志:`journalctl -u bluearchive-toolkit-official-sync.service`
- 当前可读 release`/var/lib/bluearchive-toolkit/official/current`
- 资源状态:`/var/lib/bluearchive-toolkit/official/current/official-sync-snapshot.json`
- 下载 manifest`/var/lib/bluearchive-toolkit/official/current/official-download-manifest.json`
- 历史 release`/var/lib/bluearchive-toolkit/official/versions/<id>`
- 同步 staging`/var/lib/bluearchive-toolkit/official/.staging/<id>`
- 资源写锁:`/var/lib/bluearchive-toolkit/official/.official-sync.lock`
- 运行期目录:`/run/bluearchive-toolkit/`
standalone `--daemon` 模式:
- 进程日志:`<state-dir>/bat-daemon.log`
- 结构化事件日志:`<state-dir>/bat-events.jsonl`
- RPC socket`<state-dir>/bat.sock`
- PID 文件:`<state-dir>/bat.pid`
- daemon 状态:`<state-dir>/bat-status.json`
- 控制锁:`<state-dir>/bat-control.lock`
### 生产维护命令
```bash
sudo -u bat /opt/bluearchive-toolkit/bin/bat refresh --output /var/lib/bluearchive-toolkit/official
sudo -u bat /opt/bluearchive-toolkit/bin/bat refresh --force --output /var/lib/bluearchive-toolkit/official
sudo -u bat /opt/bluearchive-toolkit/bin/bat verify --output /var/lib/bluearchive-toolkit/official
sudo -u bat /opt/bluearchive-toolkit/bin/bat repair --output /var/lib/bluearchive-toolkit/official
sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit
sudo -u bat /opt/bluearchive-toolkit/bin/bat clean-stable --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit
```
如果后台 daemon 正在运行,并且 `refresh` 没有显式指定另一套同步参数,`refresh` / `refresh --force` 会通过 RPC 唤醒或排队后台进程;带 `--output`、server-info、connection-group、app-version、platforms、snapshot、curl 或 unzip 等显式参数时,`refresh` 会作为一次性前台同步运行,但不能写入 live daemon 正在管理的同一资源目录,否则会返回 locked。`verify` 发现远端变化、本地缺失或校验失败时返回非 0;`repair` 会走官方同步链路重新下载必要文件,但同样不能和 live daemon 并行写同一资源目录;`clean-stable` 只清理 `.part``.tmp`、失效或损坏的 PID/socket/锁,不删除正式资源。
### 升级
升级只替换 `/opt/bluearchive-toolkit/bin/bat` symlink,不直接覆盖旧 binary
```bash
NEW_VERSION="<new-version-or-git-sha>"
cargo build --release -p bat-infrastructure --bin bat
sudo install -d -o root -g root -m 0755 \
/opt/bluearchive-toolkit/releases/"${NEW_VERSION}"
sudo install -o root -g root -m 0755 \
target/release/bat \
/opt/bluearchive-toolkit/releases/"${NEW_VERSION}"/bat
sudo systemctl stop bluearchive-toolkit-official-sync.service
sudo ln -sfn \
/opt/bluearchive-toolkit/releases/"${NEW_VERSION}"/bat \
/opt/bluearchive-toolkit/bin/bat
sudo systemctl start bluearchive-toolkit-official-sync.service
systemctl status bluearchive-toolkit-official-sync.service
journalctl -u bluearchive-toolkit-official-sync.service -n 100 --no-pager
```
升级后执行:
```bash
sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor \
--output /var/lib/bluearchive-toolkit/official \
--state-dir /run/bluearchive-toolkit
```
### 回滚
回滚同样只切 symlink,不删除资源目录和 manifest
```bash
PREVIOUS_VERSION="<previous-version-or-git-sha>"
sudo systemctl stop bluearchive-toolkit-official-sync.service
sudo ln -sfn \
/opt/bluearchive-toolkit/releases/"${PREVIOUS_VERSION}"/bat \
/opt/bluearchive-toolkit/bin/bat
sudo systemctl start bluearchive-toolkit-official-sync.service
journalctl -u bluearchive-toolkit-official-sync.service -n 100 --no-pager
```
当前官方资源同步的本地状态位于 `/var/lib/bluearchive-toolkit/official`,生产读取入口是 `/var/lib/bluearchive-toolkit/official/current`。普通 binary 回滚不需要回滚资源目录;如果要测试可能改动 manifest/schema 的版本,先备份当前 release 状态文件和 bootstrap cache
```bash
sudo -u bat tar -C /var/lib/bluearchive-toolkit/official \
-czf /var/lib/bluearchive-toolkit/official-state-backup.tgz \
official-bootstrap-cache.json \
current/official-sync-snapshot.json \
current/official-download-manifest.json
```
如果业务层需要热更新、热重载或发布新资源,应该由上层服务在观察到 `--json` report 或 snapshot 变化后决定。Rust 同步进程只负责拉取、校验和维护本地状态。
---
## 模式 4:完整生产环境部署
当前不可用。API Server、数据库迁移、Web 管理后台和发布编排尚未实现;不要按完整服务端产品部署本仓库。
---
## 数据库备份
### 手动备份
```bash
# PostgreSQL
pg_dump -h your.server.com -U bat_user -d bluearchive_toolkit > backup.sql
# Redis
redis-cli -h your.server.com -p 6379 -a password BGSAVE
```
### 自动备份
启动备份服务:
```bash
docker compose -f deployments/docker-compose.remote-db.yml --profile backup up -d
```
备份文件位置:`deployments/backups/`
---
## 监控
### 查看日志
```bash
# 数据库日志
docker logs bat-postgres
# Redis 日志
docker logs bat-redis
```
### 健康检查
```bash
# 检查容器状态
docker compose -f deployments/docker-compose.remote-db.yml ps
# 检查 PostgreSQL
docker exec bat-postgres pg_isready -U bat_user
# 检查 Redis
docker exec bat-redis redis-cli ping
```
---
## 故障排查
### 无法连接数据库
1. 检查防火墙是否开放端口
2. 检查 `pg_hba.conf` 配置
3. 检查密码是否正确
4. 检查数据库是否启动
### 性能问题
1. 查看数据库连接数
2. 检查慢查询日志
3. 优化索引
4. 调整数据库参数
---
更多当前状态请查看 `CURRENT_STATUS.md``docs/reports/CURRENT_GAPS.md` 和本文件中的健康检查命令。