444 lines
33 KiB
Markdown
444 lines
33 KiB
Markdown
# Intelligent Planet Ops Runbook
|
||
|
||
This runbook is for deployment, on-call, and maintenance engineers. End-user UI flows live in the [Intelligent Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md); this document only covers shell, Docker, logs, environment variables, and troubleshooting.
|
||
|
||
## Docker Initialization and Access
|
||
|
||
Initialize a new machine before starting the application services:
|
||
|
||
```bash
|
||
zsh ./planet.sh init --non-motion-agent && zsh ./planet.sh start --non-motion-agent
|
||
```
|
||
|
||
The entry point still requires `zsh`, `curl`, and reachable package repositories. Before synchronizing Python and frontend dependencies, `init` prepares Docker:
|
||
|
||
- Reuse working Docker, Compose v2, and Buildx (at least 0.17.0).
|
||
- On Ubuntu / Ubuntu WSL, use apt to install the missing parts of `docker.io`, `docker-compose-v2`, and `docker-buildx`. When Docker CE CLI is already installed, use the configured Docker CE repository and corresponding plugin packages to keep the package family consistent.
|
||
- If the local daemon is unavailable, check that `docker.service` exists, then enable and start it. WSL must have systemd enabled; unavailable service management produces an explicit Docker preparation error.
|
||
- If the current user cannot read and write the Docker socket, check for `usermod`, install its `passwd` package when needed, and add the user to the `docker` group. This group grants privileged control of the local Docker engine. The script uses `sudo` to refresh group access as the original user and continue the original command with its arguments preserved. It does not depend on `sg` or run application processes as root.
|
||
|
||
When elevation is needed, sudo authentication runs in the foreground. Missing sudo for an unprivileged user, authentication failure, repository errors, or insufficient versions after installation stop initialization with a specific error.
|
||
|
||
Subsequent `planet.sh start` and other service commands in the same old terminal also refresh Docker group membership when it has been granted but is not yet active. Open a new Ubuntu session to use `docker` directly in the terminal.
|
||
|
||
When Docker Desktop is present but its WSL integration is unavailable, the script asks the operator to start Desktop and enable WSL Integration for the distribution. Unreachable remote or rootless endpoints produce a diagnostic for that environment; neither case installs a second local engine automatically. Automatic installation on other operating systems is not currently supported.
|
||
|
||
`planet.sh` calls `scripts/lib/docker-bootstrap.zsh` for preparation. Missing CLI, missing service units, socket permissions, and stopped daemons receive separate diagnostics. Advice to start `docker.socket` is shown only after confirming that the unit exists. Verify the result with:
|
||
|
||
```bash
|
||
docker info
|
||
docker compose version
|
||
docker buildx version
|
||
```
|
||
|
||
## Database Initialization and Connection Checks
|
||
|
||
`init` and `start` reconcile PostgreSQL / Redis containers through Compose, including port configuration on existing containers. A plain `docker start` cannot apply configuration changes. Compose failures retain their specific errors, such as an occupied port, instead of falling back to an old container and reporting success.
|
||
|
||
The container's `pg_isready` check only establishes that the server accepts connections; it does not validate the host backend's address and credentials. Once containers are healthy, both initialization and backend startup run `scripts/check_database_connection.py` using the backend's effective `DATABASE_URL`. It checks the local PostgreSQL published port and executes a read-only `SELECT 1`. Startup performs this check before preparing the AI Provider image and stops immediately on failure. Initialization only creates tables and seed data after the check passes.
|
||
|
||
- If the actual local port mapping is still missing or mismatched, the script recreates PostgreSQL once from Compose while preserving its data volume, then checks again. A second failure stops initialization.
|
||
- Authentication, database-name, and network failures stop before schema changes. Diagnostics show the host, port, and database name without passwords, full connection strings, or raw driver exceptions.
|
||
- A process-level `DATABASE_URL` overrides `backend/.env`. Changing `POSTGRES_PASSWORD` alone updates neither the connection string nor the password stored in an existing data volume. Existing environment files are retained and their effective configuration must be checked.
|
||
- Explicit external databases do not require a local container mapping. Host networking also does not require published ports. Both still require the real connection check.
|
||
|
||
For `port is already allocated` or `address already in use`, inspect `docker ps` port information and `ss -ltnp '( sport = :5432 )'`. With WSL mirrored networking, also inspect Windows listeners. Initialization does not kill other database services to acquire a port, delete data volumes, or reset passwords.
|
||
|
||
## First Startup
|
||
|
||
```bash
|
||
./planet.sh start
|
||
```
|
||
|
||
Default behavior:
|
||
|
||
- Starts PostgreSQL and Redis
|
||
- Starts AI Provider
|
||
- Starts the backend API
|
||
- Starts the frontend Vite dev server
|
||
- Prints Earth, console, Playground, and backend API doc URLs
|
||
|
||
First startup seeds two default accounts (see `DEFAULT_LOGIN_USERS` in `backend/app/db/session.py`):
|
||
|
||
| Username | Password | Role |
|
||
| --- | --- | --- |
|
||
| `admin` | `admin123` | `super_admin` |
|
||
| `linkong` | `LK12345678` | `super_admin` |
|
||
|
||
Both seed accounts are created with `email_verified = TRUE` and can log into the console immediately. Any other account must either go through the public registration flow described in the Manual, or be created via `./planet.sh createuser`.
|
||
|
||
Specify custom ports:
|
||
|
||
```bash
|
||
./planet.sh start -b 8001 -f 3001 -a 8101
|
||
```
|
||
|
||
| Flag | Meaning |
|
||
| --- | --- |
|
||
| `-b <port>` | Backend port |
|
||
| `-f <port>` | Frontend port |
|
||
| `-a <port>` | AI Provider port |
|
||
| `--allow-lan` | Enable LAN access |
|
||
| `--verbose` | Show extra command output |
|
||
|
||
## Stop and Per-Module Restart
|
||
|
||
Stop everything:
|
||
|
||
```bash
|
||
./planet.sh stop
|
||
```
|
||
|
||
Stops backend, AI Provider, frontend, PostgreSQL, Redis.
|
||
|
||
Per-module restart:
|
||
|
||
```bash
|
||
./planet.sh restart # full
|
||
./planet.sh restart -b # backend
|
||
./planet.sh restart -f # frontend
|
||
./planet.sh restart -a # AI Provider
|
||
./planet.sh restart -d # database
|
||
```
|
||
|
||
Per-module restart is preferred during development to avoid interrupting unrelated services.
|
||
|
||
## Destructive Reset
|
||
|
||
```bash
|
||
./planet.sh destroy
|
||
```
|
||
|
||
`destroy` returns a local development environment to a near-empty project state. It requires typing `Y` before it runs; source files and existing `.env` files are preserved.
|
||
|
||
Cleanup order and boundaries:
|
||
|
||
- If `planet_postgres` is running, the script first clears the `public` schema in `planet_db`. This prevents old `collected_data.is_current = true` rows from making Earth OOBE report `ready=true` if Docker volume removal later fails.
|
||
- Docker cleanup targets resources whose Compose project is `planet`, plus the explicit volumes `planet_postgres_data`, `planet_redis_data`, `postgres_data`, and `redis_data`; do not delete unlabeled volumes by a broad `planet_*` pattern, because another local project could own them.
|
||
- Local build state removes `.venv`, frontend `node_modules` / `dist`, Planet state, and scattered Python / Vite cache directories. `$PLANET_CACHE_DIR/downloads` is preserved so upstream raw downloads such as CelesTrak can survive database resets and local rebuild cleanup.
|
||
|
||
After the reset, run `./planet.sh init` again to recreate tables and default seed data. Old collected records are not restored, and Earth OOBE is evaluated from the backend's real collection state on the next visit. When CelesTrak later returns its "GP data has not updated" HTTP 403, the backend first reuses the preserved download cache to repopulate the database; if no active cache exists, it tries valid CelesTrak fallback group caches; if no download cache exists at all, wait for the next CelesTrak update window or use Space-Track. Datasource `Clear Data` and `Clear Cache` actions in the console do not delete `$PLANET_CACHE_DIR/downloads/celestrak`.
|
||
|
||
## Health Check
|
||
|
||
```bash
|
||
./planet.sh health
|
||
```
|
||
|
||
Checks:
|
||
|
||
- `planet_*` container status
|
||
- Backend `/health`
|
||
- AI Provider `/health`
|
||
- Frontend reachability
|
||
|
||
If anything reports offline, check the corresponding logs first.
|
||
|
||
## Logs
|
||
|
||
Recent logs:
|
||
|
||
```bash
|
||
./planet.sh log
|
||
```
|
||
|
||
Follow:
|
||
|
||
```bash
|
||
./planet.sh log -f # frontend: ~/.local/state/planet/frontend.log
|
||
./planet.sh log -b # backend: ~/.local/state/planet/backend.log
|
||
./planet.sh log -a # AI Provider: planet_aiprovider container logs
|
||
```
|
||
|
||
## CLI User Creation
|
||
|
||
```bash
|
||
./planet.sh createuser
|
||
```
|
||
|
||
Interactively prompts for username, password, and role; writes the user with `email_verified = TRUE` directly.
|
||
|
||
Use when:
|
||
|
||
- SMTP is not yet configured but an admin account is needed now
|
||
- Pre-seeding internal test accounts
|
||
- Public registration is unavailable for any reason and a fallback is required
|
||
|
||
For ordinary user onboarding, configure SMTP at `/settings -> SMTP Email` first and let users self-register at `/register`.
|
||
|
||
## LAN / WSL Access
|
||
|
||
```bash
|
||
./planet.sh start --allow-lan
|
||
```
|
||
|
||
Useful for:
|
||
|
||
- Starting in WSL, accessing from Windows browser
|
||
- Demoing Earth from a phone or tablet
|
||
- Other LAN machines reaching the same dev instance
|
||
|
||
On Windows, the repository-root `planet.cmd` can be used as a one-click entrypoint. It requests Administrator privileges, enters the `Ubuntu` WSL distribution at `/home/linkong/planet`, runs `./planet.sh restart --allow-lan`, opens `http://localhost:3000/earth` after a successful restart, and leaves the terminal inside a WSL shell for log inspection. If the local WSL distribution name or checkout path differs, adjust the `wsl.exe -d ... --cd ...` arguments in `planet.cmd` first.
|
||
|
||
On a new Windows machine, check the WSL generation first:
|
||
|
||
```powershell
|
||
wsl -l -v
|
||
```
|
||
|
||
Planet development should use WSL2. WSL1 has different networking, filesystem, and process behavior, and can surface as Bun package-manager commands returning only `An unknown error occurred (Unexpected)`, unstable port release, or LAN behavior that does not match the script's assumptions. Convert the distribution if it still runs as WSL1:
|
||
|
||
```powershell
|
||
wsl --set-version Ubuntu 2
|
||
```
|
||
|
||
`--allow-lan` directly exposes the frontend, backend, and AI Provider from the development machine: frontend `3000`, backend `8000`, and AI Provider `8010`. Before startup, the script checks all three ports. If WSL/Linux cannot release a port and a Windows-side listener or stale `portproxy` rule owns it, the script requests Administrator PowerShell cleanup. When Planet runs in WSL, Windows can usually reach it through `localhost`; other LAN machines reaching the Windows LAN IP still need Windows Firewall allow rules.
|
||
|
||
Diagnose in this order:
|
||
|
||
```bash
|
||
# From the shell running Planet
|
||
curl http://localhost:3000
|
||
curl http://localhost:8000/health
|
||
curl http://localhost:8010/health
|
||
ss -ltnp | grep -E ':3000|:8000|:8010'
|
||
```
|
||
|
||
If the services are running but the LAN IP still fails, first remove stale `portproxy` rules and confirm Windows Firewall allows the ports. The script checks this automatically and requests Administrator PowerShell when needed. Manual fallback commands:
|
||
|
||
```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
|
||
```
|
||
|
||
LAN devices should use the Windows external ports, for example `http://<Windows LAN IP>:3000/earth`, `http://<Windows LAN IP>:8000/health`, and `http://<Windows LAN IP>:8010/health`.
|
||
|
||
## AI Provider Environment and Builds
|
||
|
||
AI Provider runtime configuration lives in two places:
|
||
|
||
| Location | Best for | Notes |
|
||
| --- | --- | --- |
|
||
| `aiprovider/.env` | Team-shared local defaults | Read by Docker Compose as `env_file` |
|
||
| `~/.zshrc` | Personal provider/model/key/proxy | `planet.sh` reads common `AI_*`, `SERVICE_*`, `PYTHON_IMAGE`, `UV_IMAGE` lines |
|
||
|
||
Recommended form:
|
||
|
||
```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
|
||
```
|
||
|
||
By default `planet.sh` only statically parses simple `export KEY=value` lines from `~/.zshrc`. When complex shell expansion is required, opt in explicitly:
|
||
|
||
```bash
|
||
PLANET_LOAD_ZSHRC_ENV=source ./planet.sh start -a
|
||
```
|
||
|
||
To ignore `~/.zshrc` entirely:
|
||
|
||
```bash
|
||
PLANET_LOAD_ZSHRC_ENV=0 ./planet.sh start -a
|
||
```
|
||
|
||
The AI Provider image only rebuilds when code, Dockerfile, Compose config, or Python dependencies change. After changing keys or base URL, restarting the container is enough:
|
||
|
||
```bash
|
||
./planet.sh restart -a
|
||
```
|
||
|
||
Rebuild detection is based on a content fingerprint rather than only file mtimes. `planet.sh` hashes the `aiprovider/` files, `aiprovider/Dockerfile`, `pyproject.toml`, `uv.lock`, `PYTHON_IMAGE`, `UV_IMAGE`, and the dependency fingerprint into `AI_PROVIDER_BUILD_FINGERPRINT`; Docker writes it into the image label `planet.aiprovider.build-fingerprint`. If the existing `planet-aiprovider:latest` image has a matching label, the script skips rebuild and refreshes the local stamp. Older images without the label fall back to the state/cache stamp.
|
||
|
||
Docker builds use `uv sync --frozen`. To make container builds reuse the host uv mirror configuration, the script resolves the first config file in this order and mounts it into the build as a BuildKit secret at `/root/.config/uv/uv.toml`:
|
||
|
||
1. The current `UV_CONFIG_FILE`
|
||
2. Repository-root `uv.toml`
|
||
3. `${XDG_CONFIG_HOME:-~/.config}/uv/uv.toml`
|
||
4. `~/.uv/uv.toml`
|
||
|
||
If none exists, the script creates an empty state file for the secret so Compose does not fail on a missing file. Before Docker build it unsets `UV_DEFAULT_INDEX`, `UV_INDEX_URL`, and `UV_EXTRA_INDEX_URL`, keeping the build tied to the explicit `UV_CONFIG_FILE`. For a temporary Tsinghua mirror, place this in repository-root `uv.toml`:
|
||
|
||
```toml
|
||
[[index]]
|
||
name = "tsinghua"
|
||
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
|
||
default = true
|
||
```
|
||
|
||
Start and restart use fingerprint-based build detection by default. To explicitly reuse a local image for one command, add --no-build:
|
||
|
||
```bash
|
||
./planet.sh start --no-build
|
||
./planet.sh restart -a --no-build
|
||
```
|
||
|
||
This option affects only AI Provider and keeps other startup checks enabled. A missing local image is an error, and the old image is never stamped as containing current code. When Compose v2 is available, builds, startup and build-capability checks use v2 only and preserve its failure. Compose v1 is considered only when v2 is unavailable.
|
||
|
||
Diagnose slow builds:
|
||
|
||
| Symptom | Common cause | Fix |
|
||
| --- | --- | --- |
|
||
| Large `transferring context` | build context includes unrelated frontend / data files | `.dockerignore` ships only required files |
|
||
| `uv sync --frozen` is slow | first build, cold cache, or missing uv mirror config | wait for the first build; later runs reuse BuildKit cache; configure `uv.toml` when needed |
|
||
| Old keys still in effect after edit | container not restarted | `./planet.sh restart -a` |
|
||
| Code changed but the image did not rebuild | fingerprint still matches the image label | Confirm the change is under `aiprovider/`, Dockerfile, or Python dependency inputs; delete `planet-aiprovider:latest` and retry if needed |
|
||
|
||
## SMTP Email (Required for Public Registration)
|
||
|
||
Public registration and email verification depend on SMTP. Administrators configure host, port, username, password, from-address, and TLS mode at `/settings -> SMTP Email` in the console, then use the "Send Test Email" button to verify. Settings are persisted in the `system_settings.smtp` row.
|
||
|
||
When SMTP is unset, `POST /api/v1/auth/register` returns `503 EMAIL_PROVIDER_NOT_CONFIGURED` and the frontend surfaces a clear error. The operational fallback is `./planet.sh createuser`.
|
||
|
||
One-time codes are stored in Redis under `otp:{purpose}:{email}` with a 600-second TTL. The key is invalidated after 5 invalid attempts. Resend cooldown is 60 seconds, enforced via `otp_rate:{purpose}:{email}`.
|
||
|
||
## Error Cause Catalog
|
||
|
||
Every planet.sh log_error retains its context and reads its diagnostic code, cause and remedy directly from the Chinese table. AI Provider build failures also inspect the full build log. Rows are matched in order using case-insensitive literal fragments separated by semicolons; specific errors precede summaries. Codes are diagnostic identifiers, not process exit codes; failure still returns a nonzero status. Matching fragments below intentionally retain the Chinese shell messages.
|
||
|
||
For each newly confirmed cause, update both language tables with a stable code, distinguishing evidence and a regression case before integrating it into the script. Unverified failures remain P_UNKNOWN; the script must not append guessed causes to documentation. scripts/lib/error-diagnostics.zsh reads the table. Do not put vertical bars in cells. scripts/harness/test_error_diagnostics.py checks classification, bilingual codes and runtime wording.
|
||
|
||
<!-- planet-error-catalog:start -->
|
||
| Error code | Matching fragments (semicolon-separated) | Cause / established failure | Remedy |
|
||
| --- | --- | --- | --- |
|
||
| P_PROXY_EXTERNAL | PLANET_PROXY_EXTERNAL | Docker proxy settings belong to another configuration source or have been edited manually. | Inspect daemon.json, systemd proxy settings and the Planet ownership record before changing ownership; existing settings are preserved. |
|
||
| P_PROXY_CHANGED | PLANET_PROXY_CONFIG_CHANGED | Docker proxy settings changed after detection. | Wait for concurrent configuration work to finish and retry without overwriting it. |
|
||
| P_PROXY_ROLLBACK | PLANET_PROXY_ROLLBACK_FAILED | Docker or previously running containers could not be restored after a failed proxy update. | Inspect daemon and container logs; the original configuration was restored. Use daemon.json.planet-proxy.bak for manual recovery if necessary. |
|
||
| P_PROXY_CONFIG | PLANET_PROXY_CONFIG_FAILED;Docker 构建代理检测失败;Docker 构建代理更新失败 | Automatic proxy detection, validation or service update failed. | Check Python 3, curl, Docker and sudo access; updates attempt rollback and proxy credentials are excluded from error output. |
|
||
| P_PROXY_NO_ROUTE | PLANET_PROXY_NO_ROUTE | No configured host proxy could reach the required build registries, and direct probes also failed. | Restore a working proxy or repair direct networking, DNS and registry addresses; disabling builds does not repair connectivity. |
|
||
| P_REGISTRY_RATE_LIMIT | 429 Too Many Requests;toomanyrequests;pull rate limit | The registry responded but imposed a request-rate or image-pull quota limit; consult the response for the specific limit. | Avoid repeated retries and follow upstream retry guidance. For anonymous pull quotas, check docker login identity and allowance; do not mistake throttling for an unreachable proxy. |
|
||
| P_DNS | no such host;temporary failure in name resolution;could not resolve host | Name resolution failed; the log alone does not identify the DNS configuration or upstream fault. | Check DNS and proxy resolution in the Docker environment; compare shell and daemon resolution. |
|
||
| P_TLS_CERT | x509:;certificate verify failed;certificate signed by unknown authority | TLS certificate validation failed. | Check time, certificate chain and proxy CA; install trusted certificates without disabling verification. |
|
||
| P_PROXY_AUTH | proxy authentication required;407 proxy | The proxy requires authentication and rejected the request. | Check daemon proxy credentials and permissions; keep credentials out of the repository and logs. |
|
||
| P_NETWORK_TIMEOUT | i/o timeout;tls handshake timeout;context deadline exceeded;deadlineexceeded | A connection or TLS handshake timed out; the log alone cannot distinguish proxy, DNS and IPv6 faults. | Compare direct and proxied requests; check daemon proxy settings, DNS and IPv6 routes. Shell proxy settings do not configure the daemon. |
|
||
| P_CONNECTION_REFUSED | connection refused | The destination refused the connection; its listener, address or port may be wrong. | Identify whether the target is a proxy, database or registry, then check its listener and service state. |
|
||
| P_REGISTRY_AUTH | pull access denied;unauthorized:;insufficient_scope;denied: requested access | Registry access was denied or the current identity cannot pull the image. | Verify the image name, repository permissions and docker login identity. |
|
||
| P_IMAGE_TAG | manifest unknown;manifest not found | The registry cannot find the requested manifest or tag. | Check PYTHON_IMAGE, UV_IMAGE and other tags, including architecture support. |
|
||
| P_DISK_FULL | no space left on device | Disk space or inodes are exhausted. | Check df -h, df -i and docker system df; remove only confirmed disposable data, never database volumes as a troubleshooting shortcut. |
|
||
| P_DOCKER_SOCKET | permission denied while trying to connect;刷新组权限后仍无法访问 Docker socket | The current user cannot access the Docker socket. | Check socket ownership and docker group membership; run ./planet.sh init for permissions and open a new terminal. |
|
||
| P_DOCKER_SERVICE | 没有可用的 docker.service;Docker Engine 启动失败;cannot connect to the docker daemon;无法连接 daemon | Docker is not ready or the client cannot reach the current endpoint. | Check systemctl status docker, docker context ls and journalctl -u docker.service; connection failure does not prove Docker is absent. |
|
||
| P_DOCKER_DESKTOP | 检测到 Docker Desktop,但当前 WSL | Docker Desktop or its WSL integration is unavailable. | Start Docker Desktop and enable WSL Integration for this distribution. |
|
||
| P_DOCKER_ENDPOINT | 当前 Docker 使用其他 context 或远程/rootless endpoint | The selected remote or rootless Docker endpoint is unavailable. | Check docker context ls, DOCKER_HOST and the target service; do not replace it with a local engine automatically. |
|
||
| P_BUILDX | 未检测到 docker buildx;buildx 0.17;buildx >=;buildx v;当前 docker compose 不支持 build;安装后 Docker CLI、Compose v2 | Docker build plugins are missing, too old or unable to provide build support. | Check docker buildx version and docker compose version; install or upgrade the plugins required by the project. |
|
||
| P_COMPOSE_MISSING | 未检测到可用的 Docker Compose | No usable Compose command was found. | Install the Compose v2 plugin and verify docker compose version; a v2 operation failure must not trigger v1 fallback. |
|
||
| P_LOCAL_IMAGE_MISSING | 已指定 --no-build,但本地没有 AI Provider 镜像 | Builds were disabled but the AI Provider image is not present locally. | Build or import the image before using --no-build; the option never builds automatically. |
|
||
| P_SUDO | 缺少 sudo | The privilege escalation tool required for dependency setup is unavailable. | Ask an administrator to install and authorize sudo, or provision the dependencies in advance. |
|
||
| P_UNSUPPORTED_OS | Docker 自动安装目前支持;未识别系统包管理器 | The current system is outside the automatic installation support scope. | Install dependencies through supported system procedures and retry. |
|
||
| P_LOCKFILE_CHANGED | 修改了 uv.lock | Dependency preparation unexpectedly changed the lockfile. | Check manifest and lockfile consistency; use frozen installation without implicit lockfile updates. |
|
||
| P_DEPENDENCIES | 安装失败;安装后仍不可用;安装完成后仍未找到;未找到 .venv/bin/python;自动安装后仍无法解析运行时;未找到 Vite Bun 入口;缺少 mediapipe/opencv-python;仍无法导入 mediapipe/opencv-python;需要 openssl | A required dependency failed to install, is missing or is unavailable in the active environment. | Inspect the installer log, network, package sources and PATH; use Bun for frontend and the project uv environment for Python. |
|
||
| P_ARGUMENT | 未知参数;非法端口;需要端口号;需要逗号分隔;--motion-agent-mode 需要;--motion-agent-wsl-usbipd-busid 需要;用法: ./planet.sh | The command or an argument does not match the supported format. | Check ./planet.sh usage and correct the arguments before retrying. |
|
||
| P_PORT | 地址已被占用;端口仍不可用;清理失败,请检查占用进程;port is already allocated;address already in use | The requested port is occupied or cannot be bound in the host environment. | Check ss and Windows Get-NetTCPConnection; identify the owner before changing ports or stopping the service. |
|
||
| P_CAMERA | live 模式缺少可用摄像头;未找到可打开并能读帧的摄像头 | Motion Agent cannot capture frames from a usable camera. | Check hardware, permissions and WSL USB forwarding; use --non-motion-agent or explicit dry-run when live capture is not needed. |
|
||
| P_DB_CONNECTION | 后端数据库连接检查失败 | The backend database connection or published-port check failed. | Inspect the probe output and verify DATABASE_URL, credentials, database name and port; container health alone is insufficient. |
|
||
| P_DB_START | 数据库启动失败;数据库重启失败;PostgreSQL 启动失败;数据库初始化失败 | Database startup, health checks or initialization did not complete. | Inspect PostgreSQL and Redis logs and the specific database error; do not troubleshoot by deleting volumes. |
|
||
| P_BACKEND_START | 后端进程已退出;后端启动失败 | The backend exited or did not pass its health check. | Use ./planet.sh log -b and resolve import, configuration, database or application initialization errors first. |
|
||
| P_AI_START | AI Provider 启动失败 | AI Provider did not start or pass its health check. | Use ./planet.sh log -a and check runtime configuration, ports and container exit details. |
|
||
| P_FRONTEND_START | 前端启动失败 | The frontend did not pass its startup health check. | Use ./planet.sh log -f and check Bun, dependencies, the Vite entry point and ports. |
|
||
| P_MOTION_START | Motion Agent 启动失败 | Motion Agent failed to start. | Use ./planet.sh log -m and check dependencies, cameras and input mode. |
|
||
| P_ACCOUNT_INPUT | 用户名不能为空;密码不能为空;密码长度不能少于;两次输入的密码不一致 | User creation input failed validation. | Supply a username and matching passwords that satisfy the minimum length. |
|
||
| P_HTTP_HEALTH | 不可访问: | The specified HTTP endpoint failed its access check. | Check the URL, listener, firewall and local or LAN routing; check certificate trust for HTTPS. |
|
||
| P_COMPOSE_FAILED | Docker Compose 执行失败;docker-compose v1 执行失败 | The selected Compose command failed without a more specific classified cause. | Inspect the preceding original error; repair an installed Compose v2 instead of installing v1 as a fallback. |
|
||
| P_BUILD_FAILED | AI Provider 镜像构建失败;failed to solve | Image build failed without evidence matching a known specific cause. | Inspect the earliest specific error in aiprovider_build.log and add the confirmed cause and a regression case to this catalog. |
|
||
| P_UNKNOWN | — | Unclassified; the available evidence does not establish the cause. | Retain the error and command; after verifying the root cause, update both language catalogs and add a regression case. |
|
||
<!-- planet-error-catalog:end -->
|
||
|
||
### Docker Daemon Proxy and Build Networking
|
||
|
||
Shell HTTP_PROXY / HTTPS_PROXY settings do not automatically configure a running Docker daemon. When the shell can reach a registry through its proxy but Docker pulls time out, compare direct requests, proxied requests and daemon settings. HTTP 401, 403 and 429 establish a registry response, not pull authorization or remaining quota. Verify authentication and rate limits with the actual build; these responses must not cause a reachable proxy to be disabled.
|
||
|
||
Before an actual AI Provider build, the script reads HTTPS_PROXY, HTTP_PROXY and ALL_PROXY, including lowercase forms. It validates HTTP/HTTPS candidates against the registries selected by PYTHON_IMAGE and UV_IMAGE, respecting NO_PROXY. A working proxy is configured for the local Linux Docker Engine. Missing or unusable proxies cause a direct probe and removal of stale Planet-managed proxy settings. If neither route works, P_PROXY_NO_ROUTE stops the build. A host without a proxy and a daemon already using direct access receives no proxy configuration. Fingerprint cache hits and --no-build skip probing. This is not a background monitor: proxy availability is checked on the next actual build.
|
||
|
||
scripts/docker_proxy.py manages the proxies section of /etc/docker/daemon.json and a root-only ownership record at /etc/docker/planet-proxy-state.json. Administrator settings, systemd proxy settings and manually edited proxies are not overwritten. Unchanged settings need neither elevation nor a restart. Updates use the existing sudo flow, preserve unrelated Docker settings, save daemon.json.planet-proxy.bak, validate configuration, restart Docker and start previously running containers. Failures trigger rollback; check container health after recovery. Credentials travel through environment variables or restricted files and are excluded from logs. Docker Desktop, remote and rootless daemons retain their own settings without local daemon.json changes. Proxy addresses come from the environment, never a machine-specific port in the repository.
|
||
|
||
The AI Provider Dockerfile uses the bundled BuildKit frontend to avoid a separate docker/dockerfile image fetch. Python and uv base images and package downloads still require network access. --no-build explicitly reuses a local image; it does not repair build networking. Build errors are recorded in ${XDG_STATE_HOME:-$HOME/.local/state}/planet/aiprovider_build.log. Verify restored services with ./planet.sh health.
|
||
|
||
## Troubleshooting Order
|
||
|
||
```bash
|
||
./planet.sh health # 1. service state
|
||
./planet.sh log # 2. recent logs
|
||
./planet.sh log -f # 3. per-module logs
|
||
./planet.sh log -b
|
||
./planet.sh log -a
|
||
./planet.sh restart -f # 4. restart only the affected module
|
||
./planet.sh restart -b
|
||
./planet.sh restart -a
|
||
./planet.sh restart -d # 5. database / cache issues
|
||
./planet.sh restart # 6. full restart if still broken
|
||
```
|
||
|
||
## Development Command Conventions
|
||
|
||
Backend setup and script initialization use the lockfile:
|
||
|
||
```bash
|
||
uv python install 3.14
|
||
uv sync --frozen --group dev
|
||
```
|
||
|
||
`--frozen` rejects implicit `uv.lock` rewrites, which is the desired behavior on new machines, CI, and Docker builds. Dependency upgrades should explicitly update `pyproject.toml` / `uv.lock` on a development machine and commit the lockfile.
|
||
|
||
Frontend must use Bun:
|
||
|
||
```bash
|
||
cd frontend
|
||
bun install
|
||
bun run dev
|
||
bun run build
|
||
```
|
||
|
||
Do not use `npm run ...`. In the WSL / Windows mixed environment Bun avoids Node/npm path inconsistencies.
|
||
|
||
`./planet.sh start` / `init` now runs `bun install` before startup instead of only checking whether the Vite entry file exists. This keeps new devices, cleaned `node_modules`, and lockfile changes synchronized before the console loads, avoiding dynamic-import 500s caused by missing frontend dependencies.
|
||
|
||
Validate the frontend build:
|
||
|
||
```bash
|
||
source ~/.zshrc && bun run build
|
||
```
|
||
|
||
Use `bun run dev` during development; Vite HMR refreshes the browser after source saves. `bun run build` only writes the `dist` artifact and does not refresh an already-open dev page.
|
||
|
||
To inspect the production bundle with automatic reload after successful builds:
|
||
|
||
```bash
|
||
bun run preview:auto
|
||
```
|
||
|
||
To watch sources and rebuild continuously without starting the preview server:
|
||
|
||
```bash
|
||
bun run build:watch
|
||
```
|
||
|
||
Backend dependencies are managed with uv:
|
||
|
||
```bash
|
||
uv sync
|
||
uv run pytest backend/tests/test_otp_service.py
|
||
```
|
||
|
||
## Earth Boundary PMTiles Operations
|
||
|
||
1. In the console, open `Operations and Configuration -> Earth Content -> Boundary Precision` to save boundary source configuration. The local config is written to `config/earth-boundary-sources.local.json`; do not commit it.
|
||
2. Click "Build high precision boundaries", or switch the Earth toolbar settings gear to High Precision for the first build. The backend downloads the three source packages to `data/earth-boundary-sources/`, writes the source manifest, and invokes the PMTiles build script.
|
||
3. The builder requires `tippecanoe` and `pmtiles` on PATH. Missing tools return a clear API error and do not write data-source collection records.
|
||
4. A successful production build outputs `frontend/public/earth/data/boundaries/earth-boundaries-china-pov-v1.pmtiles` and its manifest.
|
||
5. After deployment, open Earth, enable "Border Lines", and inspect China's southeast coast, Taiwan, Hainan, the South China Sea, Zangnan, Kosovo, and Gaza for hover behavior and boundary policy.
|
||
6. If no high-precision manifest/PMTiles exists locally, Earth uses the bundled `frontend/public/earth/data/countries-admin0.min.geojson` fallback. If high-precision assets exist but tile requests fail, troubleshoot PMTiles range requests, manifest provider, Nginx `.pmtiles` static serving, and sha256 consistency.
|
||
|
||
## Related Docs
|
||
|
||
- [planet.sh Startup Mechanism](/home/ray/dev/linkong/planet/docs/technical/en/ops-planet-sh-startup.md)
|
||
- [System Service Control](/home/ray/dev/linkong/planet/docs/technical/en/backend-system-service-control.md)
|
||
- [Docker + Compose + Buildx Upgrade](/home/ray/dev/linkong/planet/docs/technical/en/ops-docker-compose-buildx-upgrade.md)
|
||
- [Data Collectors](/home/ray/dev/linkong/planet/docs/technical/en/backend-collectors.md)
|