18 KiB
智能星球运维手册
这份手册面向部署、值班和二次开发的运维人员。客户面向的 UI 使用流程见 智能星球使用手册,本手册只覆盖 shell、Docker、日志、环境变量和故障排查。
Docker 初始化与访问权限
新机器应先执行初始化,再启动应用服务:
zsh ./planet.sh init --non-motion-agent && zsh ./planet.sh start --non-motion-agent
脚本入口仍需先安装 zsh、curl,并保证软件源可访问。init 在同步 Python 和前端依赖之前准备 Docker:
- 已有可用的 Docker、Compose v2 和 Buildx(至少 0.17.0)时直接复用。
- Ubuntu / Ubuntu WSL 缺少依赖时,通过 apt 安装
docker.io、docker-compose-v2、docker-buildx中缺失的部分。若已安装 Docker CE CLI,则使用已配置的 Docker CE 软件源和对应插件包,避免混用软件包系列。 - 本地 Docker daemon 未运行时,确认
docker.service存在后启用并启动它。WSL 必须启用 systemd;如果服务管理不可用,脚本会在 Docker 准备阶段明确报错。 - 当前用户不能读写 Docker socket 时,检查并补装提供
usermod的passwd包,将用户加入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 allocated 或 address 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.py 的 DEFAULT_LOGIN_USERS):
| 用户名 | 密码 | 角色 |
|---|---|---|
admin |
admin123 |
super_admin |
linkong |
LK12345678 |
super_admin |
两个默认账号 email_verified 为 true,可直接登录控制台。任何在该列表之外的账号都必须走公开注册 + 邮箱验证流程(见使用手册),或用 ./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_db的publicschema。这样即使后续 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,后端会优先用保留的下载缓存重新写入数据库;如果 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/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 |
推荐写法:
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 展开时显式启用:
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/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:
- 当前环境的
UV_CONFIG_FILE - 仓库根目录
uv.toml ${XDG_CONFIG_HOME:-~/.config}/uv/uv.toml~/.uv/uv.toml
如果都不存在,脚本会创建一个空的 state 文件作为 secret,避免 Compose 的 secret file 缺失。进入 Docker 构建前会清掉 UV_DEFAULT_INDEX、UV_INDEX_URL、UV_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 一次性验证码走 Redis,key 格式 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 dev,Vite 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 操作步骤
- 在控制台
运维与配置 -> 智能星球内容 -> 国界精度保存国界源配置;本机配置写入config/earth-boundary-sources.local.json,不要提交。 - 点击“构建高精国界”,或在 Earth 页面工具栏齿轮中切到“高精”触发首次构建。后端会下载三类源到
data/earth-boundary-sources/,生成 source manifest,并调用 PMTiles 构建脚本。 - 构建器需要本机 PATH 里有
tippecanoe和pmtiles。缺工具时接口返回明确错误,不会写入数据源采集记录。 - 构建成功后应输出
frontend/public/earth/data/boundaries/earth-boundaries-china-pov-v1.pmtiles和对应 manifest。 - 部署后打开智能星球,开启“国界线”,放大中国东南海岸、台湾、海南、南海、藏南、科索沃、加沙等区域验证 hover 和边界口径。
- 如果本地没有高精 manifest/PMTiles,Earth 会使用
frontend/public/earth/data/countries-admin0.min.geojson低精度 fallback;如果高精产物存在但瓦片请求失败,按 PMTiles range 请求、manifest provider、Nginx.pmtiles静态返回和 sha256 一致性排查。