Прод-деплой через 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>
This commit is contained in:
@@ -69,6 +69,13 @@ PROD_UPLOAD_DIR=/data/uploads
|
|||||||
DEV_ACHIEVEMENTS_DIR=./data/dev/achievements
|
DEV_ACHIEVEMENTS_DIR=./data/dev/achievements
|
||||||
PROD_ACHIEVEMENTS_DIR=/data/achievements
|
PROD_ACHIEVEMENTS_DIR=/data/achievements
|
||||||
|
|
||||||
|
# ─── ОБРАЗЫ ПРОДА (реестр для docker compose pull на Pi) ──────────────────────
|
||||||
|
# Образы собираются под arm64 на ПК (scripts/build-push.sh) и пушатся в Gitea-реестр,
|
||||||
|
# а Pi их тянет (docker compose pull). Owner в пути — строчными. Тег можно версионировать.
|
||||||
|
# Перед пушем/пуллом: docker login gitea.arseniev.info
|
||||||
|
IMAGE_REGISTRY=gitea.arseniev.info/notbigghost
|
||||||
|
IMAGE_TAG=latest
|
||||||
|
|
||||||
# ─── РЕСУРСЫ ПРОД-КОНТЕЙНЕРА (docker-compose.yml) ─────────────────────────────
|
# ─── РЕСУРСЫ ПРОД-КОНТЕЙНЕРА (docker-compose.yml) ─────────────────────────────
|
||||||
# Лимиты под Raspberry Pi. Не заданы → дефолты compose (512m / 1.5 CPU).
|
# Лимиты под Raspberry Pi. Не заданы → дефолты compose (512m / 1.5 CPU).
|
||||||
# Подними, если у Pi больше RAM/ядер.
|
# Подними, если у Pi больше RAM/ядер.
|
||||||
|
|||||||
+21
-6
@@ -32,18 +32,33 @@ VPS_TUNNEL_USER=tunnel
|
|||||||
`VPS_TUNNEL_PORT` задавать не нужно — прод-контейнер по умолчанию берёт слот **9000**.
|
`VPS_TUNNEL_PORT` задавать не нужно — прод-контейнер по умолчанию берёт слот **9000**.
|
||||||
Ресурсы (`APP_MEM_LIMIT`/`APP_CPUS`) и оффсайт-бэкап (`BACKUP_*`) — по желанию.
|
Ресурсы (`APP_MEM_LIMIT`/`APP_CPUS`) и оффсайт-бэкап (`BACKUP_*`) — по желанию.
|
||||||
|
|
||||||
## 3. Запуск
|
## 3. Запуск (образ из реестра)
|
||||||
|
Образы (`app` + `tunnel`) собираются под arm64 на ПК и пушатся в Gitea-реестр, Pi их тянет
|
||||||
|
(см. `IMAGE_REGISTRY`/`IMAGE_TAG` в `.env`). Pi 4/5 — мощный, но реестр держим как основной путь.
|
||||||
|
|
||||||
|
На ПК (Docker Desktop) — один раз `docker login gitea.arseniev.info`, далее при каждом релизе:
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d --build # поднимет app + tunnel
|
scripts/build-push.sh # buildx: arm64-сборка app+tunnel и push в реестр
|
||||||
docker compose ps # оба up; tunnel стартует после healthy app
|
```
|
||||||
docker compose logs -f tunnel # ждём строку: [tunnel] -R 9000:app:8000 -> tunnel@...
|
На 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` — должен отдать прод.
|
Открой `https://forbiddenstars.ru` — должен отдать прод.
|
||||||
|
|
||||||
|
> Альтернатива без реестра (Pi 4/5 ≥4ГБ потянет сборку): `docker compose up -d --build` прямо на Pi.
|
||||||
|
> Реестр Gitea должен быть по HTTPS с валидным сертификатом; иначе на Pi добавь его в
|
||||||
|
> `/etc/docker/daemon.json` → `insecure-registries`.
|
||||||
|
|
||||||
## Обновление
|
## Обновление
|
||||||
```bash
|
```bash
|
||||||
git pull
|
# ПК: scripts/build-push.sh
|
||||||
docker compose up -d --build
|
# Pi: git pull && docker compose pull && docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## Бэкап (полный + оффсайт на VPS)
|
## Бэкап (полный + оффсайт на VPS)
|
||||||
|
|||||||
+4
-2
@@ -15,7 +15,9 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build: .
|
build: .
|
||||||
image: forbidden-stars:latest
|
# Образ из реестра (Gitea): собирается под arm64 на ПК (scripts/build-push.sh) и тянется
|
||||||
|
# на Pi через `docker compose pull`. build: оставлен как локальный фолбэк (сборка на Pi).
|
||||||
|
image: ${IMAGE_REGISTRY:-gitea.arseniev.info/notbigghost}/forbidden-stars:${IMAGE_TAG:-latest}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
init: true # PID 1 пробрасывает сигналы → корректный SIGTERM
|
init: true # PID 1 пробрасывает сигналы → корректный SIGTERM
|
||||||
stop_grace_period: 30s # время на чек-пойнт WAL SQLite перед остановкой
|
stop_grace_period: 30s # время на чек-пойнт WAL SQLite перед остановкой
|
||||||
@@ -47,7 +49,7 @@ services:
|
|||||||
# Ключ — ./deploy/tunnel/id_tunnel (в git не идёт); его pubkey в authorized_keys у tunnel@VPS.
|
# Ключ — ./deploy/tunnel/id_tunnel (в git не идёт); его pubkey в authorized_keys у tunnel@VPS.
|
||||||
tunnel:
|
tunnel:
|
||||||
build: ./deploy/tunnel
|
build: ./deploy/tunnel
|
||||||
image: forbidden-stars-tunnel:latest
|
image: ${IMAGE_REGISTRY:-gitea.arseniev.info/notbigghost}/forbidden-stars-tunnel:${IMAGE_TAG:-latest}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
init: true
|
init: true
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
Executable
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Сборка прод-образов (app + tunnel) под linux/arm64 для Raspberry Pi и пуш в реестр.
|
||||||
|
# Запускается на машине РАЗРАБОТКИ с Docker Desktop/buildx (не на Pi).
|
||||||
|
# Реестр и тег берутся из корневого .env (IMAGE_REGISTRY / IMAGE_TAG) — те же, что в
|
||||||
|
# docker-compose.yml. Перед запуском один раз залогиниться в реестр:
|
||||||
|
# docker login gitea.arseniev.info
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
|
# Билдер с поддержкой push разных архитектур (driver docker-container) — создаём при отсутствии.
|
||||||
|
if ! docker buildx inspect fsbuilder >/dev/null 2>&1; then
|
||||||
|
docker buildx create --name fsbuilder --driver docker-container >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Эмуляция arm64 на x86-хосте (в Docker Desktop обычно уже стоит; команда идемпотентна).
|
||||||
|
docker run --privileged --rm tonistiigi/binfmt --install arm64 >/dev/null
|
||||||
|
|
||||||
|
echo "[build-push] Сборка app+tunnel под linux/arm64 и пуш в реестр…"
|
||||||
|
# bake читает docker-compose.yml: контексты build: и теги image: (с подстановкой из .env).
|
||||||
|
docker buildx bake -f docker-compose.yml --builder fsbuilder --set "*.platform=linux/arm64" --push
|
||||||
|
|
||||||
|
echo "[build-push] Готово. На Pi: docker compose pull && docker compose up -d"
|
||||||
Reference in New Issue
Block a user