From 13495de5bddd5bc27d80df8ea21313837e7731f5 Mon Sep 17 00:00:00 2001 From: x0gp Date: Mon, 6 Jul 2026 22:11:42 +0400 Subject: [PATCH] feat: add fast Docker build script and home server documentation --- ops/HOME_SERVER.md | 522 ++++++++++++++++++++++++++++++++++ server/scripts/build-fast.ps1 | 3 + 2 files changed, 525 insertions(+) create mode 100644 ops/HOME_SERVER.md diff --git a/ops/HOME_SERVER.md b/ops/HOME_SERVER.md new file mode 100644 index 0000000..be942b2 --- /dev/null +++ b/ops/HOME_SERVER.md @@ -0,0 +1,522 @@ +# 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`). diff --git a/server/scripts/build-fast.ps1 b/server/scripts/build-fast.ps1 index bec2a23..c15436e 100644 --- a/server/scripts/build-fast.ps1 +++ b/server/scripts/build-fast.ps1 @@ -33,6 +33,9 @@ try { # Run docker build docker build --build-arg BINARY_PATH=$BinPath -t $Tag -f Dockerfile.fast . + if ($LASTEXITCODE -ne 0) { + throw "Docker build failed with exit code $LASTEXITCODE" + } Write-Host "`nDocker image '$Tag' built successfully!" -ForegroundColor Green }