331 lines
14 KiB
Markdown
331 lines
14 KiB
Markdown
# Planet Ops Runbook
|
|
|
|
This runbook is for deployment, on-call, and maintenance engineers. End-user UI flows live in the [Planet Manual](/home/ray/dev/linkong/planet/docs/technical/en/manual.md); this document only covers shell, Docker, logs, environment variables, and troubleshooting.
|
|
|
|
## 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/cache, and scattered Python / Vite cache directories.
|
|
|
|
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.
|
|
|
|
## 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
|
|
```
|
|
|
|
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}`.
|
|
|
|
## 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.
|
|
|
|
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)
|