Files
planet/docs/technical/zh/ops-runbook.md
rayd1o a54fcdbeed
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled
ci / backend (pull_request) Has been cancelled
ci / frontend (pull_request) Has been cancelled
ci / delivery (pull_request) Has been cancelled
release: bump version to 0.74.3
2026-09-13 02:17:55 +08:00

18 KiB
Raw Blame History

智能星球运维手册

这份手册面向部署、值班和二次开发的运维人员。客户面向的 UI 使用流程见 智能星球使用手册,本手册只覆盖 shell、Docker、日志、环境变量和故障排查。

Docker 初始化与访问权限

新机器应先执行初始化,再启动应用服务:

zsh ./planet.sh init --non-motion-agent && zsh ./planet.sh start --non-motion-agent

脚本入口仍需先安装 zshcurl,并保证软件源可访问。init 在同步 Python 和前端依赖之前准备 Docker

  • 已有可用的 Docker、Compose v2 和 Buildx至少 0.17.0)时直接复用。
  • Ubuntu / Ubuntu WSL 缺少依赖时,通过 apt 安装 docker.iodocker-compose-v2docker-buildx 中缺失的部分。若已安装 Docker CE CLI则使用已配置的 Docker CE 软件源和对应插件包,避免混用软件包系列。
  • 本地 Docker daemon 未运行时,确认 docker.service 存在后启用并启动它。WSL 必须启用 systemd如果服务管理不可用脚本会在 Docker 准备阶段明确报错。
  • 当前用户不能读写 Docker socket 时,检查并补装提供 usermodpasswd 包,将用户加入 docker 组。该组拥有管理本机 Docker 的高权限。脚本使用 sudo 以原用户身份刷新组权限并继续原命令,保留参数,不依赖 sg,也不会把应用进程改为 root 用户运行。

需要提权时,脚本会在前台请求 sudo 认证。普通用户缺少 sudo、认证失败、软件源不可用或安装后版本仍不满足要求时初始化会停止并报告具体原因。

同一旧终端随后执行 planet.sh start 等命令时,也会检测已加入但尚未生效的 Docker 组权限并刷新。若要在终端直接使用 docker,重新打开 Ubuntu 会话即可。

Docker Desktop 已存在但 WSL 集成不可用时,脚本提示启动 Desktop 并启用当前发行版的 WSL Integration。已有远程或 rootless endpoint 无法连接时,提示检查当前环境;这些情况不会自动安装另一套本地引擎。其他操作系统的自动安装暂未支持。

安装逻辑由 planet.sh 调用 scripts/lib/docker-bootstrap.zsh;缺少 CLI、没有服务单元、socket 权限不足和 daemon 未启动会分别诊断。仅在确认 docker.socket 单元存在时才给出启动该单元的建议。验证准备结果可执行:

docker info
docker compose version
docker buildx version

数据库初始化与连接检查

init 会先通过 Compose 同步 PostgreSQL / Redis 容器配置,包括已有容器的端口映射;仅执行 docker start 无法应用配置变化。Compose 同步失败时会保留具体错误,例如端口被占用,不会继续复用旧容器并报告成功。

容器内部的 pg_isready 只检查服务是否接受连接,不能证明宿主机上的后端使用正确地址和密码。容器健康后,init 通过 scripts/check_database_connection.py 读取与后端相同的有效 DATABASE_URL,检查本地 PostgreSQL 的实际发布端口并执行只读 SELECT 1;通过后才显示“数据库服务已就绪”并创建表和默认数据。

  • 如果本地实际端口映射仍缺失或不匹配,脚本会保留数据卷,按 Compose 配置重建一次 PostgreSQL 并重新检查;再次失败就停止。
  • 认证、库名或网络错误会在建表前停止,诊断只显示目标主机、端口和库名,不输出密码、完整连接串或驱动异常原文。
  • 进程环境变量中的 DATABASE_URL 优先于 backend/.env。单独修改 POSTGRES_PASSWORD 不会自动更新连接串,也不会改变已有数据卷内的密码。已有环境文件会保留,需要核对其有效配置。
  • 显式配置的外部数据库不要求本地容器端口匹配host 网络模式也不要求发布端口,两者仍须通过实际连接检查。

出现 port is already allocatedaddress already in use 时,检查 docker ps 的端口信息和 ss -ltnp '( sport = :5432 )'WSL 镜像网络下还需检查 Windows 侧监听。初始化不会为了占用数据库端口而自动结束其他数据库服务,也不会删除数据卷或重设密码。

首次启动

./planet.sh start

默认行为:

  • 启动 PostgreSQL 和 Redis
  • 启动 AI Provider
  • 启动后端 API
  • 启动前端 Vite dev server
  • 输出 Earth、控制台、Playground 和后端 API 文档入口

首次启动会自动写入两个默认账号(见 backend/app/db/session.pyDEFAULT_LOGIN_USERS

用户名 密码 角色
admin admin123 super_admin
linkong LK12345678 super_admin

两个默认账号 email_verifiedtrue,可直接登录控制台。任何在该列表之外的账号都必须走公开注册 + 邮箱验证流程(见使用手册),或用 ./planet.sh createuser 命令式创建。

可指定端口:

./planet.sh start -b 8001 -f 3001 -a 8101
参数 含义
-b <port> 后端端口
-f <port> 前端端口
-a <port> AI Provider 端口
--allow-lan 允许局域网访问
--verbose 显示更多命令输出

启停与按模块重启

停止全部:

./planet.sh stop

会停止后端、AI Provider、前端、PostgreSQL、Redis。

按模块重启:

./planet.sh restart        # 全量
./planet.sh restart -b     # 后端
./planet.sh restart -f     # 前端
./planet.sh restart -a     # AI Provider
./planet.sh restart -d     # 数据库

按模块重启适合日常开发,能避免无关服务被打断。

破坏性重置

./planet.sh destroy

destroy 用于把本地开发环境退回到接近空项目的状态。执行前需要输入 Y 确认;源码和现有 .env 配置文件会保留。

清理顺序和边界:

  • 如果 planet_postgres 正在运行,脚本会先清空 planet_dbpublic schema。这样即使后续 Docker volume 删除失败,旧的 collected_data.is_current = true 也不会让 Earth OOBE 继续显示 ready=true
  • Docker 清理只针对 Compose project 为 planet 的资源,以及显式列出的 planet_postgres_dataplanet_redis_datapostgres_dataredis_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后端会优先用保留的下载缓存重新写入数据库如果 active 缓存不存在,会尝试有效 CelesTrak 分组缓存作为 fallback如果下载缓存也不存在只能等待 CelesTrak 下一次更新窗口或使用 Space-Track。控制台里的数据源“删除数据库”和“清理缓存”不会删除 $PLANET_CACHE_DIR/downloads/celestrak

健康检查

./planet.sh health

会检查:

  • planet_* 容器状态
  • 后端 /health
  • AI Provider /health
  • 前端页面可达性

如果某项显示 offline优先看对应日志。

日志

最近日志:

./planet.sh log

持续跟随:

./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 容器日志

命令式创建用户

./planet.sh createuser

交互式提示用户名、密码、角色,直接落库并标记 email_verified = TRUE

适用场景:

  • SMTP 还没配置好,但需要先发账号给一名管理员
  • 想批量预置内部测试账号
  • 公开注册流程因任何原因不可用,需要应急兜底

正式用户开通推荐走控制台 /settings -> SMTP 邮件 配好发件后,让用户在 /register 自助注册。

局域网 / WSL 访问

./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 版本:

wsl -l -v

Planet 开发环境建议使用 WSL2。WSL1 下网络、文件系统和进程模型与 Linux 差异更大,可能表现为 Bun 包管理命令只返回 An unknown error occurred (Unexpected)、端口释放不稳定,或局域网访问行为与脚本预期不一致。若发行版仍是 WSL1可转换

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 防火墙允许访问。

建议按顺序排查:

# 在运行 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 处理;自动请求被取消时,手动兜底命令如下:

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/earthhttp://<Windows局域网IP>:8000/healthhttp://<Windows局域网IP>:8010/health

AI Provider 环境变量与构建

AI Provider 运行期配置可以放在两处:

位置 适合内容 说明
aiprovider/.env 团队约定的本地默认配置 Docker Compose 作为 env_file 读取
~/.zshrc 个人 provider、模型、密钥、代理 planet.sh 启动时读取常见 AI_*SERVICE_*PYTHON_IMAGEUV_IMAGE

推荐写法:

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=valueKEY=value 行。需要复杂 shell 展开时显式启用:

PLANET_LOAD_ZSHRC_ENV=source ./planet.sh start -a

完全忽略 ~/.zshrc

PLANET_LOAD_ZSHRC_ENV=0 ./planet.sh start -a

AI Provider 镜像只在代码、Dockerfile、Compose 配置或相关 Python 依赖变化时重建。修改密钥或 Base URL 后只需重启容器:

./planet.sh restart -a

重建判断使用内容 fingerprint而不是只看文件 mtime。planet.sh 会把 aiprovider/ 文件、aiprovider/Dockerfilepyproject.tomluv.lockPYTHON_IMAGEUV_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_INDEXUV_INDEX_URLUV_EXTRA_INDEX_URL 这类环境变量,只保留明确的 UV_CONFIG_FILE,让本地和容器里的依赖解析更可复现。需要临时使用清华源时,可在仓库根目录准备:

[[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 一次性验证码走 Rediskey 格式 otp:{purpose}:{email}TTL 600 秒。错误尝试 5 次后该 key 失效;重发冷却 60 秒,由 otp_rate:{purpose}:{email} 控制。

故障排查顺序

./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. 仍无法恢复时全量重启

开发命令约定

后端和脚本初始化统一使用锁文件:

uv python install 3.14
uv sync --frozen --group dev

--frozen 会拒绝隐式改写 uv.lock适合新机器、CI 和 Docker 构建。需要升级依赖时,应先在开发机明确更新 pyproject.toml / uv.lock,再提交锁文件。

前端必须使用 Bun

cd frontend
bun install
bun run dev
bun run build

不要使用 npm run ...。项目在 WSL / Windows 混合环境优先依赖 Bun避免 Node/npm 路径差异。

./planet.sh start / init 会在启动前执行一次 bun install,而不是只检查 Vite 入口文件是否存在。这样新设备、清过 node_modules 的环境或 lockfile 已变更的环境,都能在进入控制台前同步前端依赖,避免动态 import 因缺失依赖返回 500。

验证前端构建:

source ~/.zshrc && bun run build

开发时继续使用 bun run devVite HMR 会在保存源码后刷新浏览器。bun run build 只生成 dist 产物,不会刷新已经打开的 dev 页面。

需要看生产包并在构建成功后自动刷新时使用:

bun run preview:auto

只想监听源码并持续构建,不启动预览服务时使用:

bun run build:watch

后端依赖通过 uv 管理:

uv sync
uv run pytest backend/tests/test_otp_service.py

Earth 国界 PMTiles 操作步骤

  1. 在控制台 运维与配置 -> 智能星球内容 -> 国界精度 保存国界源配置;本机配置写入 config/earth-boundary-sources.local.json,不要提交。
  2. 点击“构建高精国界”,或在 Earth 页面工具栏齿轮中切到“高精”触发首次构建。后端会下载三类源到 data/earth-boundary-sources/,生成 source manifest并调用 PMTiles 构建脚本。
  3. 构建器需要本机 PATH 里有 tippecanoepmtiles。缺工具时接口返回明确错误,不会写入数据源采集记录。
  4. 构建成功后应输出 frontend/public/earth/data/boundaries/earth-boundaries-china-pov-v1.pmtiles 和对应 manifest。
  5. 部署后打开智能星球,开启“国界线”,放大中国东南海岸、台湾、海南、南海、藏南、科索沃、加沙等区域验证 hover 和边界口径。
  6. 如果本地没有高精 manifest/PMTilesEarth 会使用 frontend/public/earth/data/countries-admin0.min.geojson 低精度 fallback如果高精产物存在但瓦片请求失败按 PMTiles range 请求、manifest provider、Nginx .pmtiles 静态返回和 sha256 一致性排查。

相关文档