Files
x0gp/ops/HOME_SERVER.md
T

523 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# x0gp — Orange Pi 5 Pro Deployment Guide
Практический гайд по развёртыванию x0gp на **Orange Pi 5 Pro** через
**Coolify** в фазе PoC и MVP. Цель — production-like среда с минимумом
ручной настройки, используя уже имеющееся железо и платформу.
Дата создания: 2026-06-18.
Дата обновления (Orange Pi 5 Pro + Coolify): 2026-06-18.
Связанные документы:
- `../server/PLAN.md` секция 13 — общее описание.
- `../ARCHITECTURE.md` ADR-010/011 — почему Orange Pi 5 Pro + Coolify.
---
## 1. Платформа
### 1.1. Orange Pi 5 Pro (уже есть)
| Параметр | Значение |
|---|---|
| SoC | Rockchip RK3588S |
| CPU | 8 cores (4× Cortex-A76 @ 2.4 GHz + 4× Cortex-A55 @ 1.8 GHz) |
| RAM | 4 / 8 / 16 / 32 GB LPDDR4x (зависит от версии; уточнить) |
| GPU | Mali-G610 MP4 |
| **NPU** | **6 TOPS (RKNN)** — для CV-инференса на борту |
| Сеть | 2× 2.5 GbE + Wi-Fi 6 |
| USB | 2× USB 3.0 |
| Хранилище | eMMC (опц.) + microSD + NVMe через PCIe (если подключён) |
| ОС | Ubuntu (уже стоит) |
**Что проверить на твоей плате:**
- RAM (сколько: 4/8/16/32 GB).
- Охлаждение (радиатор + вентилятор — RK3588S троттлит без них).
- Хранилище (NVMe или microSD — для продакшна лучше NVMe).
- Coolify: версия, какие сервисы уже развёрнуты.
### 1.2. Coolify (уже развёрнут)
Self-hosted PaaS, UI для управления Docker-сервисами. Версия >= 4.0.
Что даёт нам:
- UI деплоя из Git-репо (push-to-deploy).
- Управление доменами + SSL (Let's Encrypt).
- Управление env-vars и секретами.
- Встроенные сервисы: PostgreSQL, Redis, MinIO, Plausible, Uptime Kuma.
- Логи, метрики, рестарт политики.
- Версионирование деплоев + rollback.
---
## 2. Подготовка Orange Pi
### 2.1. Хранилище (важно!)
По умолчанию Coolify может ставить сервисы на microSD — это медленно и
microSD изнашивается. Рекомендую:
1. Подключить **NVMe SSD** через PCIe (M.2 2230/2242).
2. Перенести `/var/lib/docker` на NVMe.
3. Либо в настройках Coolify указать custom docker-data-root.
Если NVMe нет — можно начать и на microSD, но обязательно на хорошей
(A2-rated, минимум 32 GB).
### 2.2. Охлаждение
RK3588S под нагрузкой греется (особенно NPU). Без охлаждения — троттлинг,
потеря производительности.
- Установить радиатор на SoC (идёт в комплекте, проверить).
- Добавить вентилятор 5V (питание от GPIO или USB).
- `armbianmonitor` или `s-tui` для мониторинга температуры.
- Целевая температура: < 70°C под нагрузкой.
### 2.3. Swap (если RAM 4-8 GB)
- Создать swap-файл 4-8 GB на NVMe (если есть):
```bash
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```
### 2.4. Обновления
```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git ufw fail2ban unattended-upgrades
sudo apt install -y python3-pip python3-venv # для CV-сервиса
sudo apt install -y libatlas-base-dev libopenblas-dev # для numpy/onnx
```
---
## 3. Сеть
### 3.1. Физическая схема
```
[Internet] -- [роутер провайдера] -- [WAN порт Orange Pi #1, 2.5 GbE]
|
v
[Orange Pi 5 Pro]
|
| LAN порт Orange Pi #2, 2.5 GbE
v
[Опц.: коммутатор]
|
v
[x0gp-track AP]
/ \
+-------+ +-------+
| камера 1 | машинки
| камера 2 | (Wi-Fi)
+--------+ +-------+
```
### 3.2. Настройка LAN-порта
```bash
# /etc/netplan/99-x0gp-lan.yaml
network:
version: 2
renderer: networkd
ethernets:
eth1: # второй порт — LAN к трассе
addresses:
- 10.0.0.1/24
dhcp4: no
```
```bash
sudo netplan apply
```
### 3.3. Wi-Fi точка доступа (x0gp-track)
Используем встроенный Wi-Fi 6 или внешний USB-адаптер (предпочтительно —
меньше нагрузка на SoC). Hostapd + dnsmasq:
```bash
sudo apt install -y hostapd dnsmasq
```
`/etc/hostapd/hostapd.conf`:
```
interface=wlan0
driver=nl80211
ssid=x0gp-track
hw_mode=g
channel=6
wmm_enabled=1
ieee80211n=1
wpa=2
wpa_passphrase=<сложный пароль>
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
```
`/etc/dnsmasq.conf`:
```
interface=wlan0
dhcp-range=10.0.0.100,10.0.0.200,12h
domain=x0gp.local
```
NAT для выхода машинок в интернет (для OTA и связи с Orange Pi):
```bash
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
```
Сохранить: `sudo apt install -y iptables-persistent && sudo netfilter-persistent save`.
### 3.4. Проброс портов на роутере
Открыть на домашнем роутере и пробросить на Orange Pi (статический IP от
провайдера):
- 80/tcp → Orange Pi:80 (для LE challenge)
- 443/tcp → Orange Pi:443 (для Caddy)
Если Orange Pi за роутером с NAT — настроить DMZ или port-forward.
---
## 4. Coolify: сервисы
### 4.1. Создание проекта
1. Зайти в Coolify UI (обычно `http://orange-pi-ip:8000`).
2. Создать новый Project: `x0gp`.
3. Внутри — Environment: `production`.
### 4.2. Сервисы через Coolify UI
| Сервис | Назначение | Ресурс |
|---|---|---|
| **PostgreSQL + TimescaleDB** | Основная БД + телеметрия | 1-2 GB RAM |
| **Redis** | Сессии, pub/sub, лобби | 256-512 MB |
| **MinIO** | S3-совместимое хранилище (replay) | по объёму |
| **api-gateway** | REST + WS, stateless | 256 MB |
| **race-engine** | Authoritative tick 60 Hz | 512 MB |
| **prometheus** | Метрики | 512 MB |
| **grafana** | Дашборды | 256 MB |
| **caddy** | Reverse proxy + LE | 128 MB |
### 4.3. Нативно (systemd) — не в Coolify
Эти компоненты требуют прямого доступа к железу, поэтому запускаются
через systemd:
| Сервис | Назначение |
|---|---|
| `x0gp-agent-linker.service` | Связь с ESP32-S3 машинками по Wi-Fi LAN |
| `x0gp-cv-tracker.service` | Overhead-CV, инференс на NPU |
| `x0gp-node-exporter.service` | Метрики Orange Pi (CPU, RAM, диск, температура) |
Конфиги: `/etc/systemd/system/x0gp-*.service`.
---
## 5. Доступ из интернета (Caddy + LE через Coolify)
Coolify автоматически провизит Let's Encrypt сертификаты для сервисов,
которым назначен домен.
### 5.1. Домены
| Сервис | Домен (пример) |
|---|---|
| API | `api.x0gp.ru` |
| Frontend (React) | `app.x0gp.ru` |
| Grafana | `grafana.x0gp.ru` |
### 5.2. DNS
A-записи указывают на статический IP Orange Pi:
```
api.x0gp.ru. A <статический IP>
app.x0gp.ru. A <статический IP>
grafana.x0gp.ru. A <статический IP>
```
### 5.3. SSL
Coolify при создании сервиса с доменом сам:
1. Запрашивает LE-сертификат через ACME challenge.
2. Прописывает сертификат в Caddy.
3. Обновляет автоматически.
### 5.4. Базовая аутентификация
Для Grafana/Prometheus/Admin — добавить basic auth через Caddy или
Cloudflare Access (опц.).
---
## 6. NPU и CV-инференс
### 6.1. RKNN Toolkit 2
Установка (на Orange Pi):
```bash
sudo apt install -y python3-pip python3-venv
python3 -m venv ~/cv-venv
source ~/cv-venv/bin/activate
pip install --upgrade pip
pip install rknn-toolkit2 onnx onnxruntime-rknn ultralytics opencv-python numpy
```
### 6.2. Конвертация модели (на PC)
YOLOv8n(детекция машинок):
```python
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
model.export(format='rknn', imgsz=640)
```
Полученный `.rknn` кладём в `/opt/x0gp/cv/models/`.
### 6.3. Запуск инференса
```python
from rknnlite.api import RKNNLite
import cv2, numpy as np
rknn = RKNNLite()
rknn.load_rknn('/opt/x0gp/cv/models/yolov8n.rknn')
rknn.init_runtime()
# ... capture frame, run inference, parse boxes ...
```
Ожидаемая производительность на Orange Pi 5 Pro:
- YOLOv8n 640×640: 30-60 FPS на NPU.
- YOLOv8n 320×320: 60-120 FPS.
### 6.4. cv-tracker как systemd-сервис
`/etc/systemd/system/x0gp-cv-tracker.service`:
```ini
[Unit]
Description=x0gp CV Tracker (overhead cameras)
After=network.target
[Service]
Type=simple
User=x0gp
WorkingDirectory=/opt/x0gp/cv
Environment="PATH=/home/x0gp/cv-venv/bin"
ExecStart=/home/x0gp/cv-venv/bin/python tracker.py
Restart=always
RestartSec=5
StandardOutput=journal
[Install]
WantedBy=multi-user.target
```
---
## 7. Бэкапы
### 7.1. Стратегия
- **Ежедневно**: `pg_dump` БД + MinIO bucket snapshots.
- **Еженедельно**: rclone на внешнее S3-совместимое (Backblaze B2 / Yandex Object Storage).
- **Ежемесячно**: тест восстановления.
### 7.2. Скрипт бэкапа
`/opt/x0gp/scripts/backup.sh`:
```bash
#!/bin/bash
set -euo pipefail
BACKUP_DIR=/opt/x0gp/backups/$(date +%Y-%m-%d)
mkdir -p "$BACKUP_DIR"
# Postgres
docker exec $(docker ps -qf "name=postgres") pg_dump -U x0gp -Fc x0gp > "$BACKUP_DIR/x0gp.dump"
# MinIO (через mc client)
docker exec $(docker ps -qf "name=minio") mc mirror /data "$BACKUP_DIR/minio/"
# Конфиги
tar czf "$BACKUP_DIR/configs.tar.gz" \
/opt/x0gp/cv/ \
/etc/systemd/system/x0gp-*.service \
/opt/x0gp/repo/.env.example
# Retention
find /opt/x0gp/backups/ -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
echo "[$(date)] backup completed: $BACKUP_DIR"
```
### 7.3. Off-site (опционально)
```bash
rclone sync /opt/x0gp/backups/ b2:x0gp-backups/ \
--transfers 4 --checkers 8 --stats 30s
```
---
## 8. Мониторинг
### 8.1. Внутренний (Coolify + Prometheus + Grafana)
- Prometheus собирает метрики с Go-сервисов, postgres, redis, node-exporter.
- Grafana: дашборды (импортировать готовые для Go-runtime и Postgres).
- Loki (опц.) для централизованных логов.
- Алерты в Telegram через Alertmanager webhook.
### 8.2. Внешний (Uptime Kuma через Coolify)
- Uptime Kuma — внешний пинг на `https://api.x0gp.ru/health`.
- Алертит если 2+ минуты не отвечает.
- Доступен извне через поддомен `status.x0gp.ru`.
### 8.3. Ключевые дашборды Grafana
- **System**: CPU, RAM, диск, сеть, температура RK3588S (через node-exporter
+ custom exporter).
- **x0gp**: ws_connections, rtt_ms p50/p95/p99, tick_lag, drop_rate,
gateway_online.
- **DB**: postgres connections, slow queries, replication lag.
- **CV**: FPS инференса на NPU, использование NPU, число обнаруженных объектов.
- **Business**: активные гонки, DAU, конверсия заездов.
---
## 9. Безопасность
### 9.1. Чеклист
- [ ] SSH только по ключам, пароли отключены.
- [ ] Нестандартный порт SSH (например, 2222).
- [ ] fail2ban настроен (по умолчанию для ssh).
- [ ] UFW: разрешён только 80/tcp + 443/tcp + SSH (LAN only).
- [ ] Coolify UI доступен только из LAN или за basic auth.
- [ ] Postgres и Redis слушают только на 127.0.0.1.
- [ ] Все секреты в Coolify env-vars (не в git).
- [ ] Автообновления безопасности включены (`unattended-upgrades`).
- [ ] UPS для Orange Pi (важно для microSD/NVMe).
- [ ] Бэкапы шифрованы (если off-site).
### 9.2. UFW
```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 192.168.1.0/24 to any port 8000 proto tcp # Coolify UI (LAN only)
sudo ufw allow 80/tcp # LE challenge + Caddy
sudo ufw allow 443/tcp # Caddy
sudo ufw allow from 10.0.0.0/24 to any port 22 proto tcp # SSH с LAN трассы (опц.)
sudo ufw enable
```
(Если Orange Pi за NAT, 80/443 уже проброшены на роутере — это ок.)
### 9.3. Fail2Ban
```bash
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
```
---
## 10. Обслуживание
### 10.1. Ежедневно
- Проверить алерты в Telegram.
- Зайти в Grafana, посмотреть дашборды.
- Проверить Uptime Kuma.
### 10.2. Еженедельно
- Проверить, что бэкапы создаются (`ls /opt/x0gp/backups/`).
- `apt list --upgradable`, при необходимости `apt upgrade`.
- Проверить свободное место на диске.
- Проверить температуру Orange Pi.
### 10.3. Ежемесячно
- Тест восстановления из бэкапа.
- Ротация API-ключей (LE аккаунт, Coolify admin).
- `docker system prune -a` (осторожно, не удалит volumes).
- Проверка UPS (тест батареи).
### 10.4. Деплой новой версии
Через Coolify UI:
1. Push в Git → триггер автоматического деплоя (если настроен webhook).
2. Или в Coolify UI нажать "Deploy" на нужном сервисе.
3. Проверить логи, метрики, smoke-test.
---
## 11. Troubleshooting
### 11.1. "Coolify недоступен"
- `docker ps` — все контейнеры работают?
- `docker logs coolify` — смотреть ошибки.
- `sudo systemctl restart coolify` (или `docker restart coolify`).
### 11.2. "Бэкап не создаётся"
- `systemctl status x0gp-backup.timer` — таймер активен?
- `journalctl -u x0gp-backup.service` — последний запуск.
- Права на `/opt/x0gp/backups/` — пользователь `x0gp` может писать?
- Место на диске: `df -h /opt/x0gp/backups`.
### 11.3. "Высокий latency"
- Проверить `rtt_ms` в Grafana — где растёт (клиент -> edge или edge -> agent).
- `ping` от Orange Pi до роутера x0gp-track.
- Wi-Fi: проверить interference через `iw dev wlan0 survey dump`.
- NPU: не перегревается ли Orange Pi (троттлинг → медленный CV → задержка)?
### 11.4. "NPU не работает"
- `ls /dev/dri/` — есть ли render node?
- `rknn-toolkit2` версия совместима с системой?
- `dmesg | grep -i rknn` — ошибки драйвера?
- Fallback: запустить инференс на CPU ARM A76 (медленнее, но работает).
### 11.5. "Postgres тормозит"
- `pg_stat_activity` — что сейчас выполняется.
- `EXPLAIN ANALYZE` на медленных запросах.
- Проверить индексы (особенно на `telemetry (race_id, ts)`).
- NVMe не заполнен? (`df -h`)
---
## 12. Что дальше
- [ ] Проверить характеристики Orange Pi 5 Pro (RAM, охлаждение, хранилище).
- [ ] Подключить NVMe SSD и перенести Docker data root.
- [ ] Установить радиатор + вентилятор (если не стоят).
- [ ] Настроить LAN-порт (eth1) + Wi-Fi AP.
- [ ] Создать проект `x0gp` в Coolify.
- [ ] Развернуть PostgreSQL, Redis, MinIO через Coolify.
- [ ] Создать базовые сервисы api-gateway, race-engine.
- [ ] Настроить systemd-сервисы agent-linker и cv-tracker.
- [ ] Настроить бэкапы.
- [ ] Заполнить чеклист безопасности.
- [ ] Запустить PoC (1 машинка + 1 трасса 100×60 см на столе).
- [ ] Замерить baseline latency и записать в `docs/baselines/`.
После стабильной работы PoC в течение 2-4 недель — переходить к MVP (фаза S1
в `server/PLAN.md`, H1 в `hardware/PLAN.md`).