feat: add fast Docker build script and home server documentation

This commit is contained in:
x0gp
2026-07-06 22:11:42 +04:00
parent e5155c8a42
commit 13495de5bd
2 changed files with 525 additions and 0 deletions
+522
View File
@@ -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`).
+3
View File
@@ -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
}