331 lines
14 KiB
Markdown
331 lines
14 KiB
Markdown
# Planet 运维手册
|
||
|
||
这份手册面向部署、值班和二次开发的运维人员。客户面向的 UI 使用流程见 [Planet 使用手册](/home/ray/dev/linkong/planet/docs/technical/zh/manual.md),本手册只覆盖 shell、Docker、日志、环境变量和故障排查。
|
||
|
||
## 首次启动
|
||
|
||
```bash
|
||
./planet.sh start
|
||
```
|
||
|
||
默认行为:
|
||
|
||
- 启动 PostgreSQL 和 Redis
|
||
- 启动 AI Provider
|
||
- 启动后端 API
|
||
- 启动前端 Vite dev server
|
||
- 输出 Earth、控制台、Playground 和后端 API 文档入口
|
||
|
||
首次启动会自动写入两个默认账号(见 `backend/app/db/session.py` 的 `DEFAULT_LOGIN_USERS`):
|
||
|
||
| 用户名 | 密码 | 角色 |
|
||
| --- | --- | --- |
|
||
| `admin` | `admin123` | `super_admin` |
|
||
| `linkong` | `LK12345678` | `super_admin` |
|
||
|
||
两个默认账号 `email_verified` 为 `true`,可直接登录控制台。任何在该列表之外的账号都必须走公开注册 + 邮箱验证流程(见使用手册),或用 `./planet.sh createuser` 命令式创建。
|
||
|
||
可指定端口:
|
||
|
||
```bash
|
||
./planet.sh start -b 8001 -f 3001 -a 8101
|
||
```
|
||
|
||
| 参数 | 含义 |
|
||
| --- | --- |
|
||
| `-b <port>` | 后端端口 |
|
||
| `-f <port>` | 前端端口 |
|
||
| `-a <port>` | AI Provider 端口 |
|
||
| `--allow-lan` | 允许局域网访问 |
|
||
| `--verbose` | 显示更多命令输出 |
|
||
|
||
## 启停与按模块重启
|
||
|
||
停止全部:
|
||
|
||
```bash
|
||
./planet.sh stop
|
||
```
|
||
|
||
会停止后端、AI Provider、前端、PostgreSQL、Redis。
|
||
|
||
按模块重启:
|
||
|
||
```bash
|
||
./planet.sh restart # 全量
|
||
./planet.sh restart -b # 后端
|
||
./planet.sh restart -f # 前端
|
||
./planet.sh restart -a # AI Provider
|
||
./planet.sh restart -d # 数据库
|
||
```
|
||
|
||
按模块重启适合日常开发,能避免无关服务被打断。
|
||
|
||
## 破坏性重置
|
||
|
||
```bash
|
||
./planet.sh destroy
|
||
```
|
||
|
||
`destroy` 用于把本地开发环境退回到接近空项目的状态。执行前需要输入 `Y` 确认;源码和现有 `.env` 配置文件会保留。
|
||
|
||
清理顺序和边界:
|
||
|
||
- 如果 `planet_postgres` 正在运行,脚本会先清空 `planet_db` 的 `public` schema。这样即使后续 Docker volume 删除失败,旧的 `collected_data.is_current = true` 也不会让 Earth OOBE 继续显示 `ready=true`。
|
||
- Docker 清理只针对 Compose project 为 `planet` 的资源,以及显式列出的 `planet_postgres_data`、`planet_redis_data`、`postgres_data`、`redis_data`;不要按 `planet_*` 模式删除没有 label 的 volume,避免误删同机其他项目。
|
||
- 本地编译状态会删除 `.venv`、前端 `node_modules` / `dist`、Planet state,以及散落的 Python / Vite 缓存目录;`$PLANET_CACHE_DIR/downloads` 会保留,用于保存 CelesTrak 这类受上游下载窗口限制的原始文件缓存。
|
||
|
||
重置后重新执行 `./planet.sh init` 会重建表和默认数据,但不会恢复旧采集结果;首次进入 Earth 时 OOBE 会重新按后端真实采集状态判断。触发 CelesTrak 采集时,如果上游返回“本轮 GP 数据未更新”的 403,后端会优先用保留的下载缓存重新写入数据库;如果下载缓存也不存在,只能等待 CelesTrak 下一次更新窗口或使用 Space-Track 作为 fallback。
|
||
|
||
## 健康检查
|
||
|
||
```bash
|
||
./planet.sh health
|
||
```
|
||
|
||
会检查:
|
||
|
||
- `planet_*` 容器状态
|
||
- 后端 `/health`
|
||
- AI Provider `/health`
|
||
- 前端页面可达性
|
||
|
||
如果某项显示 offline,优先看对应日志。
|
||
|
||
## 日志
|
||
|
||
最近日志:
|
||
|
||
```bash
|
||
./planet.sh log
|
||
```
|
||
|
||
持续跟随:
|
||
|
||
```bash
|
||
./planet.sh log -f # 前端: ~/.local/state/planet/frontend.log
|
||
./planet.sh log -b # 后端: ~/.local/state/planet/backend.log
|
||
./planet.sh log -a # AI Provider: planet_aiprovider 容器日志
|
||
```
|
||
|
||
## 命令式创建用户
|
||
|
||
```bash
|
||
./planet.sh createuser
|
||
```
|
||
|
||
交互式提示用户名、密码、角色,直接落库并标记 `email_verified = TRUE`。
|
||
|
||
适用场景:
|
||
|
||
- SMTP 还没配置好,但需要先发账号给一名管理员
|
||
- 想批量预置内部测试账号
|
||
- 公开注册流程因任何原因不可用,需要应急兜底
|
||
|
||
正式用户开通推荐走控制台 `/settings -> SMTP 邮件` 配好发件后,让用户在 `/register` 自助注册。
|
||
|
||
## 局域网 / WSL 访问
|
||
|
||
```bash
|
||
./planet.sh start --allow-lan
|
||
```
|
||
|
||
适用于:
|
||
|
||
- WSL 中启动,Windows 浏览器访问
|
||
- 手机或平板演示 Earth
|
||
- 局域网其他机器访问同一开发实例
|
||
|
||
Windows 侧可以使用仓库根目录的 `planet.cmd` 作为一键入口。它会请求管理员权限,进入 `Ubuntu` WSL 发行版的 `/home/linkong/planet`,执行 `./planet.sh restart --allow-lan`,成功后打开 `http://localhost:3000/earth`,并把终端停留在 WSL shell 中便于继续排查日志。若本机发行版名称或项目路径不同,需要先按实际环境调整 `planet.cmd` 中的 `wsl.exe -d ... --cd ...` 参数。
|
||
|
||
新机器优先确认 WSL 版本:
|
||
|
||
```powershell
|
||
wsl -l -v
|
||
```
|
||
|
||
Planet 开发环境建议使用 WSL2。WSL1 下网络、文件系统和进程模型与 Linux 差异更大,可能表现为 Bun 包管理命令只返回 `An unknown error occurred (Unexpected)`、端口释放不稳定,或局域网访问行为与脚本预期不一致。若发行版仍是 WSL1,可转换:
|
||
|
||
```powershell
|
||
wsl --set-version Ubuntu 2
|
||
```
|
||
|
||
`--allow-lan` 会让前端、后端和 AI Provider 直接对开发机开放:前端 `3000`、后端 `8000`、AI Provider `8010`。脚本启动前会检查这三个端口;如果 WSL/Linux 侧无法释放端口,并检测到 Windows 侧 listener 或旧 `portproxy`,会请求管理员 PowerShell 清理。WSL 中运行时,Windows 本机一般可以通过 `localhost` 访问,局域网其他机器访问 Windows 局域网 IP 时还需要 Windows 防火墙放行。
|
||
|
||
建议按顺序排查:
|
||
|
||
```bash
|
||
# 在运行 Planet 的 shell 中
|
||
curl http://localhost:3000
|
||
curl http://localhost:8000/health
|
||
curl http://localhost:8010/health
|
||
ss -ltnp | grep -E ':3000|:8000|:8010'
|
||
```
|
||
|
||
如果服务已经启动但局域网 IP 仍访问失败,优先清理旧 `portproxy` 并确认 Windows 防火墙放行。脚本会自动检测并请求管理员 PowerShell 处理;自动请求被取消时,手动兜底命令如下:
|
||
|
||
```powershell
|
||
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=3000
|
||
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8000
|
||
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8010
|
||
|
||
New-NetFirewallRule -DisplayName "WSL Planet 3000" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000
|
||
New-NetFirewallRule -DisplayName "WSL Planet 8000" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8000
|
||
New-NetFirewallRule -DisplayName "WSL Planet 8010" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8010
|
||
```
|
||
|
||
局域网设备访问 Windows 对外端口,例如 `http://<Windows局域网IP>:3000/earth`、`http://<Windows局域网IP>:8000/health`、`http://<Windows局域网IP>:8010/health`。
|
||
|
||
## AI Provider 环境变量与构建
|
||
|
||
AI Provider 运行期配置可以放在两处:
|
||
|
||
| 位置 | 适合内容 | 说明 |
|
||
| --- | --- | --- |
|
||
| `aiprovider/.env` | 团队约定的本地默认配置 | Docker Compose 作为 `env_file` 读取 |
|
||
| `~/.zshrc` | 个人 provider、模型、密钥、代理 | `planet.sh` 启动时读取常见 `AI_*`、`SERVICE_*`、`PYTHON_IMAGE`、`UV_IMAGE` |
|
||
|
||
推荐写法:
|
||
|
||
```bash
|
||
export AI_PROVIDER=minimax
|
||
export AI_PROVIDER_API=anthropic-messages
|
||
export AI_BASE_URL=https://api.example.com/anthropic
|
||
export AI_API_KEY=sk-change-me
|
||
export AI_MODEL=MiniMax-M2.7
|
||
export AI_PROVIDER_SERVICE_TOKEN=change_me
|
||
```
|
||
|
||
`planet.sh` 默认只静态解析 `~/.zshrc` 中简单的 `export KEY=value` 或 `KEY=value` 行。需要复杂 shell 展开时显式启用:
|
||
|
||
```bash
|
||
PLANET_LOAD_ZSHRC_ENV=source ./planet.sh start -a
|
||
```
|
||
|
||
完全忽略 `~/.zshrc`:
|
||
|
||
```bash
|
||
PLANET_LOAD_ZSHRC_ENV=0 ./planet.sh start -a
|
||
```
|
||
|
||
AI Provider 镜像只在代码、Dockerfile、Compose 配置或相关 Python 依赖变化时重建。修改密钥或 Base URL 后只需重启容器:
|
||
|
||
```bash
|
||
./planet.sh restart -a
|
||
```
|
||
|
||
重建判断使用内容 fingerprint,而不是只看文件 mtime。`planet.sh` 会把 `aiprovider/` 文件、`aiprovider/Dockerfile`、`pyproject.toml`、`uv.lock`、`PYTHON_IMAGE`、`UV_IMAGE` 和依赖指纹合成 `AI_PROVIDER_BUILD_FINGERPRINT`,构建时写入镜像 label `planet.aiprovider.build-fingerprint`。如果现有 `planet-aiprovider:latest` 镜像的 label 与当前 fingerprint 一致,脚本会跳过 rebuild 并刷新本地 stamp;旧镜像没有 label 时才回退到 state/cache 里的 stamp 判断。
|
||
|
||
Docker 构建统一使用 `uv sync --frozen`。为了让容器构建也能复用本机 uv 镜像源配置,脚本会解析以下顺序中的第一个配置文件,并通过 BuildKit secret 挂到容器内 `/root/.config/uv/uv.toml`:
|
||
|
||
1. 当前环境的 `UV_CONFIG_FILE`
|
||
2. 仓库根目录 `uv.toml`
|
||
3. `${XDG_CONFIG_HOME:-~/.config}/uv/uv.toml`
|
||
4. `~/.uv/uv.toml`
|
||
|
||
如果都不存在,脚本会创建一个空的 state 文件作为 secret,避免 Compose 的 secret file 缺失。进入 Docker 构建前会清掉 `UV_DEFAULT_INDEX`、`UV_INDEX_URL`、`UV_EXTRA_INDEX_URL` 这类环境变量,只保留明确的 `UV_CONFIG_FILE`,让本地和容器里的依赖解析更可复现。需要临时使用清华源时,可在仓库根目录准备:
|
||
|
||
```toml
|
||
[[index]]
|
||
name = "tsinghua"
|
||
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
|
||
default = true
|
||
```
|
||
|
||
构建较慢时按层排查:
|
||
|
||
| 现象 | 常见原因 | 处理方式 |
|
||
| --- | --- | --- |
|
||
| `transferring context` 很大 | build context 含前端资源等无关文件 | `.dockerignore` 只发送必需文件 |
|
||
| `uv sync --frozen` 下载较慢 | 首次构建、缓存为空或 uv 镜像源未配置 | 等待首次完成,后续复用 BuildKit 缓存;必要时配置 `uv.toml` |
|
||
| 改密钥后仍是旧配置 | 容器未重启 | `./planet.sh restart -a` |
|
||
| 修改代码但镜像未重建 | fingerprint 与镜像 label 一致 | 确认改动是否进入 `aiprovider/`、Dockerfile 或 Python 依赖;必要时删除 `planet-aiprovider:latest` 后重试 |
|
||
|
||
## SMTP 邮件(公开注册依赖)
|
||
|
||
公开注册和邮箱验证依赖 SMTP。管理员在控制台 `/settings -> SMTP 邮件` 子 tab 中填写主机、端口、账号、密码、发件地址、TLS 模式,然后用"发送测试邮件"按钮验证。配置同时写入 `system_settings.smtp` 表行。
|
||
|
||
未配置时 `POST /api/v1/auth/register` 返回 `503 EMAIL_PROVIDER_NOT_CONFIGURED`,前端的注册流程会给出明确提示。运维兜底方式是 `./planet.sh createuser`。
|
||
|
||
OTP 一次性验证码走 Redis,key 格式 `otp:{purpose}:{email}`,TTL 600 秒。错误尝试 5 次后该 key 失效;重发冷却 60 秒,由 `otp_rate:{purpose}:{email}` 控制。
|
||
|
||
## 故障排查顺序
|
||
|
||
```bash
|
||
./planet.sh health # 1. 看服务状态
|
||
./planet.sh log # 2. 看最近日志
|
||
./planet.sh log -f # 3. 按模块查看
|
||
./planet.sh log -b
|
||
./planet.sh log -a
|
||
./planet.sh restart -f # 4. 只重启有问题的模块
|
||
./planet.sh restart -b
|
||
./planet.sh restart -a
|
||
./planet.sh restart -d # 5. 数据库 / 缓存异常时
|
||
./planet.sh restart # 6. 仍无法恢复时全量重启
|
||
```
|
||
|
||
## 开发命令约定
|
||
|
||
后端和脚本初始化统一使用锁文件:
|
||
|
||
```bash
|
||
uv python install 3.14
|
||
uv sync --frozen --group dev
|
||
```
|
||
|
||
`--frozen` 会拒绝隐式改写 `uv.lock`,适合新机器、CI 和 Docker 构建。需要升级依赖时,应先在开发机明确更新 `pyproject.toml` / `uv.lock`,再提交锁文件。
|
||
|
||
前端必须使用 Bun:
|
||
|
||
```bash
|
||
cd frontend
|
||
bun install
|
||
bun run dev
|
||
bun run build
|
||
```
|
||
|
||
不要使用 `npm run ...`。项目在 WSL / Windows 混合环境优先依赖 Bun,避免 Node/npm 路径差异。
|
||
|
||
验证前端构建:
|
||
|
||
```bash
|
||
source ~/.zshrc && bun run build
|
||
```
|
||
|
||
开发时继续使用 `bun run dev`,Vite HMR 会在保存源码后刷新浏览器。`bun run build` 只生成 `dist` 产物,不会刷新已经打开的 dev 页面。
|
||
|
||
需要看生产包并在构建成功后自动刷新时使用:
|
||
|
||
```bash
|
||
bun run preview:auto
|
||
```
|
||
|
||
只想监听源码并持续构建,不启动预览服务时使用:
|
||
|
||
```bash
|
||
bun run build:watch
|
||
```
|
||
|
||
后端依赖通过 uv 管理:
|
||
|
||
```bash
|
||
uv sync
|
||
uv run pytest backend/tests/test_otp_service.py
|
||
```
|
||
|
||
## Earth 国界 PMTiles 操作步骤
|
||
|
||
1. 在控制台 `运维与配置 -> Earth 内容 -> 国界精度` 保存国界源配置;本机配置写入 `config/earth-boundary-sources.local.json`,不要提交。
|
||
2. 点击“构建高精国界”,或在 Earth 页面工具栏齿轮中切到“高精”触发首次构建。后端会下载三类源到 `data/earth-boundary-sources/`,生成 source manifest,并调用 PMTiles 构建脚本。
|
||
3. 构建器需要本机 PATH 里有 `tippecanoe` 和 `pmtiles`。缺工具时接口返回明确错误,不会写入数据源采集记录。
|
||
4. 构建成功后应输出 `frontend/public/earth/data/boundaries/earth-boundaries-china-pov-v1.pmtiles` 和对应 manifest。
|
||
5. 部署后打开 Earth,开启“国界线”,放大中国东南海岸、台湾、海南、南海、藏南、科索沃、加沙等区域验证 hover 和边界口径。
|
||
6. 如果本地没有高精 manifest/PMTiles,Earth 会使用 `frontend/public/earth/data/countries-admin0.min.geojson` 低精度 fallback;如果高精产物存在但瓦片请求失败,按 PMTiles range 请求、manifest provider、Nginx `.pmtiles` 静态返回和 sha256 一致性排查。
|
||
|
||
## 相关文档
|
||
|
||
- [planet.sh 启动机制](/home/ray/dev/linkong/planet/docs/technical/zh/ops-planet-sh-startup.md)
|
||
- [系统服务控制](/home/ray/dev/linkong/planet/docs/technical/zh/backend-system-service-control.md)
|
||
- [Docker + Compose + Buildx 升级](/home/ray/dev/linkong/planet/docs/technical/zh/ops-docker-compose-buildx-upgrade.md)
|
||
- [数据采集系统](/home/ray/dev/linkong/planet/docs/technical/zh/backend-collectors.md)
|