From 1a61b05923af1c127e99988b515cddef4e9b4aa2 Mon Sep 17 00:00:00 2001 From: NotBigGhost Date: Sat, 27 Jun 2026 00:16:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B4-=D0=B4=D0=B5=D0=BF?= =?UTF-8?q?=D0=BB=D0=BE=D0=B9=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20Gitea-?= =?UTF-8?q?=D1=80=D0=B5=D0=B5=D1=81=D1=82=D1=80:=20arm64-=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D1=8B=20=D1=81=D0=BE=D0=B1=D0=B8=D1=80=D0=B0?= =?UTF-8?q?=D1=8E=D1=82=D1=81=D1=8F=20=D0=BD=D0=B0=20=D0=9F=D0=9A,=20Pi=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=B5=D1=82=20pull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .env.example | 7 +++++++ deploy/pi/README.md | 27 +++++++++++++++++++++------ docker-compose.yml | 6 ++++-- scripts/build-push.sh | 24 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100755 scripts/build-push.sh diff --git a/.env.example b/.env.example index 7842b1f..d97dfdd 100644 --- a/.env.example +++ b/.env.example @@ -69,6 +69,13 @@ PROD_UPLOAD_DIR=/data/uploads DEV_ACHIEVEMENTS_DIR=./data/dev/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) ───────────────────────────── # Лимиты под Raspberry Pi. Не заданы → дефолты compose (512m / 1.5 CPU). # Подними, если у Pi больше RAM/ядер. diff --git a/deploy/pi/README.md b/deploy/pi/README.md index a975d0a..8fd378b 100644 --- a/deploy/pi/README.md +++ b/deploy/pi/README.md @@ -32,18 +32,33 @@ VPS_TUNNEL_USER=tunnel `VPS_TUNNEL_PORT` задавать не нужно — прод-контейнер по умолчанию берёт слот **9000**. Ресурсы (`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 -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@... +scripts/build-push.sh # buildx: arm64-сборка app+tunnel и push в реестр +``` +На 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 -git pull -docker compose up -d --build +# ПК: scripts/build-push.sh +# Pi: git pull && docker compose pull && docker compose up -d ``` ## Бэкап (полный + оффсайт на VPS) diff --git a/docker-compose.yml b/docker-compose.yml index d41cc23..21800e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,9 @@ services: app: 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 init: true # PID 1 пробрасывает сигналы → корректный SIGTERM stop_grace_period: 30s # время на чек-пойнт WAL SQLite перед остановкой @@ -47,7 +49,7 @@ services: # Ключ — ./deploy/tunnel/id_tunnel (в git не идёт); его pubkey в authorized_keys у tunnel@VPS. 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 init: true depends_on: diff --git a/scripts/build-push.sh b/scripts/build-push.sh new file mode 100755 index 0000000..b345818 --- /dev/null +++ b/scripts/build-push.sh @@ -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"