Files
ForbiddenStarsApp/deploy/pi/README.md
T
NotBigGhostandClaude Opus 4.8 b3db5a4047 Прод на Pi: качественный единый compose, все настройки в .env
- docker-compose.yml: слот туннеля параметризован (${VPS_TUNNEL_PORT:-9000}), VPS_TUNNEL_HOST
  стал обязательным (${...:?}), лимиты ресурсов из .env (APP_MEM_LIMIT/APP_CPUS),
  stop_grace_period 30s (чек-пойнт WAL SQLite), security_opt no-new-privileges на обоих сервисах;
  healthcheck/логирование/тома сохранены (имена томов не менялись — данные не осиротеют).
- .env.example: VPS_TUNNEL_PORT по умолчанию НЕ задаётся (каждый контур берёт свой слот:
  dev→9001, prod→9000, test→9001); добавлены ADMIN_NICKNAME, DEV/PROD_ACHIEVEMENTS_DIR,
  APP_MEM_LIMIT/APP_CPUS.
- deploy/pi/README: чек-лист .env для Pi; запуск одним `docker compose up -d --build`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 23:46:33 +03:00

73 lines
4.1 KiB
Markdown

# 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. Запуск
```bash
docker compose up -d --build # поднимет app + tunnel
docker compose ps # оба up; tunnel стартует после healthy app
docker compose logs -f tunnel # ждём строку: [tunnel] -R 9000:app:8000 -> tunnel@...
```
Открой `https://forbiddenstars.ru` — должен отдать прод.
## Обновление
```bash
git pull
docker compose up -d --build
```
## Бэкап (полный + оффсайт на VPS)
`scripts/backup.sh` делает консистентный онлайн-снимок и собирает **полный** архив
`fs_<TS>.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_<TS>.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`).