Files
JWeBot/docs/runbooks/production-deployment.md
T

116 lines
3.1 KiB
Markdown

# Production Deployment
Use this runbook only after a target host has passed the zero-to-running
bootstrap and staging gate.
## Inputs
- clean repository snapshot;
- active validated profile for the target runtime user;
- configured production Python;
- operator-provided SSH alias and local privilege elevation;
- ready WeChat main window on display `:1`.
Do not place hostnames, addresses, usernames, passwords, private keys, or
profile values in the repository or command history.
## Local Gate
```sh
PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh
./tools/check-secrets.py --history
```
## Staging
Transfer a clean snapshot without `.git`, local profiles, virtualenvs, debug
state, captures, databases, or archives. On the target:
```sh
JWEBOT_RUNTIME_PYTHON=/opt/jwebot/venv/bin/python \
PATH="/opt/jwebot/venv/bin:$PATH" \
./tools/check-local.sh
```
Verify the active profile:
```sh
/opt/jwebot/venv/bin/python -m jwebot_config status
/opt/jwebot/venv/bin/python -m jwebot_config validate <profile>
```
## Pre-Cutover
Confirm:
1. WeChat main window is visible and meets minimum geometry.
2. Edge and adaptive recorder are active with stable restart counts.
3. Adaptive and legacy OCR queues are empty.
4. Edge direct/cloud outboxes have no failed backlog.
5. Edge SQLite `quick_check` is `ok`.
6. Legacy OCR services are disabled and inactive.
7. A restorable baseline exists.
## Coordinated Cutover
Elevate locally on the target and run:
```sh
JWEBOT_RUNTIME_PYTHON=/opt/jwebot/venv/bin/python \
./deploy/scripts/deploy-jwebot-production.sh \
/path/to/staged/JWeBot \
jwebot
```
The deployer prints an eight-stage progress bar and:
- records root and user service topology;
- copies root and user runtime files;
- backs up generated configuration;
- creates a SQLite online backup and runs `quick_check`;
- refuses non-empty queues or an unready WeChat window;
- installs the runtime;
- leaves legacy OCR disabled;
- verifies Edge health and adaptive restart stability;
- writes and verifies backup SHA-256 checksums;
- rolls back files, state, and unit topology on failure.
## Post-Cutover
```sh
systemctl --user is-active jwebot-edge.service
systemctl --user is-active wechat-ocr-adaptive-recorder.service
systemctl --user show wechat-ocr-adaptive-recorder.service \
-p NRestarts --value
```
```sh
printf '%s\n' '{"op":"health"}' |
/opt/jwebot/venv/bin/python \
~/.local/lib/wechat-health-watch/jwebot_edge.py respond
```
```sh
/opt/jwebot/venv/bin/python - <<'PY'
import sqlite3
from pathlib import Path
path = Path.home() / ".local/state/jwebot-edge/edge.sqlite3"
print(sqlite3.connect(f"file:{path}?mode=ro", uri=True)
.execute("pragma quick_check").fetchone()[0])
PY
```
Player-visible acceptance must use deliberate synthetic messages in the
configured group and confirm exactly one ACK and one final response.
## Rollback
If any gate fails:
1. stop further cutover attempts;
2. verify the coordinated deployer's rollback result;
3. confirm unit topology and SQLite integrity;
4. archive privacy-safe evidence under the active profile;
5. fix and rerun staging before another production attempt.