Files
ForbiddenStarsApp/deploy/pi/README.md
T
NotBigGhostandClaude Opus 4.8 1a61b05923 Прод-деплой через Gitea-реестр: arm64-образы собираются на ПК, Pi делает pull
- docker-compose.yml: image у app и tunnel → путь реестра ${IMAGE_REGISTRY}/...:${IMAGE_TAG}
  (build: оставлен фолбэком для сборки на Pi). Тома/настройки прежние.
- scripts/build-push.sh: buildx bake под linux/arm64 + push обоих образов в реестр (запуск на ПК).
- .env.example: блок ОБРАЗЫ ПРОДА (IMAGE_REGISTRY=gitea.arseniev.info/notbigghost, IMAGE_TAG=latest).
- deploy/pi/README: запуск/обновление через docker compose pull; альтернатива — сборка на Pi;
  заметка про HTTPS-реестр / insecure-registries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 00:16:04 +03:00

5.2 KiB

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:

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):

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, далее при каждом релизе:

scripts/build-push.sh        # buildx: arm64-сборка app+tunnel и push в реестр

На Pi:

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.

Обновление

# ПК:  scripts/build-push.sh
# Pi:  git pull && docker compose pull && docker compose up -d

Бэкап (полный + оффсайт на VPS)

scripts/backup.sh делает консистентный онлайн-снимок и собирает полный архив fs_<TS>.tar.gz (БД + uploads/ + achievements/) в backups/ с ротацией. Если в .env задан BACKUP_VPS_HOST — копия дополнительно уходит на VPS (оффсайт; Pi → VPS push, т.к. CGNAT).

Настройка оффсайта (один раз):

# 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).