# Raspberry Pi — ПРОД (`forbiddenstars.ru`) Pi запускает приложение **и туннель** в Docker: `docker compose up` поднимает два сервиса — `app` (FastAPI + SPA) и `tunnel` (ssh-контейнер). У `app` **портов на хост нет**, наружу он доступен только через туннель-контейнер (`ssh -R 9000:app:8000` к VPS). Публичная точка — VPS, домен `forbiddenstars.ru`. Снаружи Pi недоступен (CGNAT) — туннель сам стучится наружу. ## 1. Ключ для туннеля Туннель-контейнер ходит на `tunnel@VPS` по ключу из `deploy/tunnel/id_tunnel` (gitignored). Создай ключ и добавь его pubkey в `authorized_keys` пользователя `tunnel` на VPS: ```bash ssh-keygen -t ed25519 -f deploy/tunnel/id_tunnel -N "" ssh-copy-id -i deploy/tunnel/id_tunnel.pub tunnel@186.246.51.17 # (или вручную: содержимое deploy/tunnel/id_tunnel.pub -> /home/tunnel/.ssh/authorized_keys на VPS) ``` ## 2. .env Все настройки приложения и туннеля — в одном `.env` (контейнер форсит `APP_ENV=production`): ```bash cp .env.example .env ``` Минимально заполнить на Pi: ``` SECRET_KEY=... # python -c "import secrets;print(secrets.token_urlsafe(48))" ADMIN_USERNAME=... # логин/пароль секретной админки ADMIN_PASSWORD=... TELEGRAM_BOT_TOKEN=... # бот @BotFather; /setdomain → forbiddenstars.ru TELEGRAM_BOT_USERNAME=... VPS_TUNNEL_HOST=186.246.51.17 # читает сервис tunnel VPS_TUNNEL_USER=tunnel ``` `VPS_TUNNEL_PORT` задавать не нужно — прод-контейнер по умолчанию берёт слот **9000**. Ресурсы (`APP_MEM_LIMIT`/`APP_CPUS`) и оффсайт-бэкап (`BACKUP_*`) — по желанию. ## 3. Запуск (образ из реестра) Образы (`app` + `tunnel`) собираются под arm64 на ПК и пушатся в Gitea-реестр, Pi их тянет (см. `IMAGE_REGISTRY`/`IMAGE_TAG` в `.env`). Pi 4/5 — мощный, но реестр держим как основной путь. На ПК (Docker Desktop) — один раз `docker login gitea.arseniev.info`, далее при каждом релизе: ```powershell .\scripts\build-push.ps1 # Windows (PowerShell); на *nix — bash scripts/build-push.sh ``` > `bash scripts/build-push.sh` в PowerShell уходит в WSL и падает, если нет дистрибутива — > используй `.ps1`. Команды внутри — обычный `docker buildx`, работают и напрямую в PowerShell. На Pi: ```bash docker login gitea.arseniev.info # один раз (доступ к пакету) git pull # нужны docker-compose.yml, .env, deploy/tunnel/id_tunnel docker compose pull # тянет свежие образы из реестра docker compose up -d docker compose ps # app healthy → поднимется tunnel docker compose logs -f tunnel # ждём: [tunnel] -R 9000:app:8000 -> tunnel@... ``` Открой `https://forbiddenstars.ru` — должен отдать прод. > Альтернатива без реестра (Pi 4/5 ≥4ГБ потянет сборку): `docker compose up -d --build` прямо на Pi. > Реестр Gitea должен быть по HTTPS с валидным сертификатом; иначе на Pi добавь его в > `/etc/docker/daemon.json` → `insecure-registries`. ## Обновление ```bash # ПК: scripts/build-push.sh # Pi: git pull && docker compose pull && docker compose up -d ``` ## Бэкап (полный + оффсайт на VPS) `scripts/backup.sh` делает консистентный онлайн-снимок и собирает **полный** архив `fs_.tar.gz` (БД + `uploads/` + `achievements/`) в `backups/` с ротацией. Если в `.env` задан `BACKUP_VPS_HOST` — копия дополнительно уходит на VPS (оффсайт; Pi → VPS push, т.к. CGNAT). Настройка оффсайта (один раз): ```bash # 1) отдельный ключ бэкапа + его pubkey на VPS (юзер backup — см. deploy/vps/README.md): ssh-keygen -t ed25519 -f deploy/backup/id_backup -N "" ssh-copy-id -i deploy/backup/id_backup.pub backup@186.246.51.17 # 2) в .env заполнить BACKUP_VPS_HOST=186.246.51.17 (по желанию — BACKUP_VPS_USER/DIR/KEEP_*) # 3) разовый прогон и проверка, что архив доехал на VPS: scripts/backup.sh # 4) cron (ежедневно в 04:00): crontab -e # 0 4 * * * /home/pi/ForbidenStarsApp/scripts/backup.sh >> /var/log/fs-backup.log 2>&1 ``` Восстановление: `scripts/restore.sh backups/fs_.tar.gz` (ДЕСТРУКТИВНО — заменяет текущие данные; сначала проверь на тест-контуре). Тома — `db-data` / `uploads-data` / `achievements-data`. Логи: `docker compose logs -f app` / `... tunnel`. Если `https://forbiddenstars.ru` отдаёт 502 — значит туннель не поднят: смотри `docker compose logs tunnel` (чаще всего ключ не в `authorized_keys` на VPS или не заданы `VPS_TUNNEL_*` в `.env`).