build(deploy): build images on the server instead of publishing to a registry
ci / api (push) Successful in 50s
ci / recommender (push) Successful in 37s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (apps/web/Dockerfile, web, ) (push) Successful in 44s
release / android + release (push) Failing after 53s
ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 45s
ci / ts (packages + web) (push) Successful in 37s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, api, api) (push) Successful in 1m30s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, storage-agent, storage-agent) (push) Successful in 52s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/recommender/Dockerfile, recommender, ) (push) Successful in 28s
ci / mobile (Metro-бандл Android) (push) Successful in 49s
release / verify (push) Successful in 1m14s
ci / api (push) Successful in 50s
ci / recommender (push) Successful in 37s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (apps/web/Dockerfile, web, ) (push) Successful in 44s
release / android + release (push) Failing after 53s
ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 45s
ci / ts (packages + web) (push) Successful in 37s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, api, api) (push) Successful in 1m30s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, storage-agent, storage-agent) (push) Successful in 52s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/recommender/Dockerfile, recommender, ) (push) Successful in 28s
ci / mobile (Metro-бандл Android) (push) Successful in 49s
release / verify (push) Successful in 1m14s
- deploy/compose.yaml: every app service has `build:` (repo root context), local tags pipu-music-<service>:<version> - deploy/update.sh: git fetch → checkout tag (latest release by default, or vX.Y.Z / main) → docker compose build --pull → up -d → prune → /readyz; re-executes from a temp copy because checkout may replace the script - install.sh / .env.example: no REGISTRY, PIPU_VERSION set by update.sh, .env owned by the invoking user - release.yml: drop image publishing; release ships APK + sha256 only - ci.yml: new `docker` job builds all images without push - docs: install guide uses git clone, deployment/ci-cd updated, ADR-013 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1633b28c1a
commit
01319c58d7
11 files changed
+201
-186
No files matched your search
+49
-37
@@ -7,7 +7,10 @@
|
||||
В примерах:
|
||||
- домен — `music.example.com`, замените на свой;
|
||||
- репозиторий — `gitea.hsrv.site/mrleo1nid/pipu-music`;
|
||||
- реестр образов — `gitea.hsrv.site/mrleo1nid`.
|
||||
- каталог установки — `/opt/pipu-music`.
|
||||
|
||||
Готовые Docker-образы не публикуются: сервер клонирует репозиторий и собирает образы сам
|
||||
(`docker compose build`). Релизы в Gitea содержат только APK для Android.
|
||||
|
||||
> **Что умеет текущая версия.** В `v0.1.0` (этап M0) работают развёртывание, HTTPS и проверка связи
|
||||
> клиентов с сервером. Вход, библиотека и плеер появятся в следующих версиях
|
||||
@@ -19,12 +22,13 @@
|
||||
|
||||
| Что | Требование |
|
||||
|---|---|
|
||||
| Сервер | Linux x86_64 (Debian 12 / Ubuntu 22.04+), 4+ ядра, 8+ ГБ RAM, 20+ ГБ на диске под систему и кэши |
|
||||
| Сервер | Linux x86_64 (Debian 12 / Ubuntu 22.04+), 4+ ядра, 8+ ГБ RAM, 30+ ГБ на диске (система, образы, кэш сборки, данные) |
|
||||
| Доступ | root или пользователь с `sudo` |
|
||||
| Домен | Поддомен, которым вы управляете, например `music.example.com` |
|
||||
| Сеть | Входящие **80/tcp** и **443/tcp** (+ **443/udp** для HTTP/3) из интернета на сервер |
|
||||
| Музыка | NFS-сервер с библиотекой (подключается позже из админки) |
|
||||
| Gitea | Аккаунт с доступом к репозиторию, если пакеты и релизы приватные |
|
||||
| Интернет на сервере | Нужен при сборке: скачиваются базовые образы и зависимости Go / npm / Python |
|
||||
| Gitea | Доступ к репозиторию на чтение (если он приватный — токен или SSH-ключ) |
|
||||
|
||||
---
|
||||
|
||||
@@ -56,6 +60,18 @@ dig +short music.example.com
|
||||
curl -fsSL https://get.docker.com | sudo sh
|
||||
```
|
||||
|
||||
Добавьте своего пользователя в группу `docker`, чтобы запускать сборку без `sudo` (после этого перелогиньтесь):
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker "$USER"
|
||||
```
|
||||
|
||||
И `git`, если его нет:
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y git
|
||||
```
|
||||
|
||||
Проверьте, что есть Docker Compose v2.24 или новее (нужен для `compose.tls.yaml`):
|
||||
|
||||
```bash
|
||||
@@ -70,28 +86,21 @@ sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw allow 443/udp
|
||||
|
||||
---
|
||||
|
||||
## 4. Файлы развёртывания
|
||||
|
||||
Каталог для конфигурации:
|
||||
## 4. Клонирование репозитория
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/pipu && sudo chown "$USER" /opt/pipu && cd /opt/pipu
|
||||
```
|
||||
|
||||
Скачайте файлы из каталога `deploy/` репозитория. Пока нужная версия не вышла (в релизе `v0.1.0`
|
||||
ещё нет `compose.tls.yaml` и `Caddyfile`), берите их из ветки `main`; начиная с `v0.1.1` те же файлы
|
||||
лежат в ассетах релиза (`…/releases/download/vX.Y.Z/<файл>`).
|
||||
|
||||
```bash
|
||||
for f in compose.yaml compose.tls.yaml Caddyfile .env.example install.sh update.sh; do curl -fsSLO "https://gitea.hsrv.site/mrleo1nid/pipu-music/raw/branch/main/deploy/$f"; done
|
||||
sudo mkdir -p /opt/pipu-music && sudo chown "$USER" /opt/pipu-music
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod +x install.sh update.sh
|
||||
git clone https://gitea.hsrv.site/mrleo1nid/pipu-music.git /opt/pipu-music && cd /opt/pipu-music/deploy
|
||||
```
|
||||
|
||||
> Если репозиторий приватный, добавьте к `curl` заголовок с токеном Gitea (право `read:repository`):
|
||||
> `-H "Authorization: token <ТОКЕН>"`.
|
||||
> Если репозиторий приватный: клонируйте по SSH (`git@gitea.hsrv.site:mrleo1nid/pipu-music.git`) с ключом,
|
||||
> добавленным в Gitea, или по HTTPS с токеном (право `read:repository`) — Git спросит логин и токен вместо пароля.
|
||||
> Сохраните доступ (`git config credential.helper store` или SSH-ключ): `update.sh` делает `git fetch` при каждом обновлении.
|
||||
|
||||
Все дальнейшие команды выполняются из `/opt/pipu-music/deploy`.
|
||||
|
||||
---
|
||||
|
||||
@@ -107,35 +116,33 @@ sudo ./install.sh
|
||||
подключит админ, были видны всем контейнерам, и ставит systemd-юнит, повторяющий это после перезагрузки;
|
||||
- создаёт `.env` со случайными паролями БД, ключом поиска и межсервисным токеном.
|
||||
|
||||
Заполните в `/opt/pipu/.env`:
|
||||
Заполните в `/opt/pipu-music/deploy/.env`:
|
||||
|
||||
```ini
|
||||
REGISTRY=gitea.hsrv.site/mrleo1nid
|
||||
PIPU_VERSION=0.1.0
|
||||
|
||||
COMPOSE_FILE=compose.yaml:compose.tls.yaml
|
||||
DOMAIN=music.example.com
|
||||
ACME_EMAIL=you@example.com
|
||||
```
|
||||
|
||||
`ACME_EMAIL` — адрес, на который Let's Encrypt пишет, если с сертификатом что-то не так.
|
||||
Остальные значения менять не нужно.
|
||||
Остальные значения менять не нужно; `PIPU_VERSION` проставляет `update.sh`.
|
||||
|
||||
Если образы в Gitea приватные, войдите в реестр токеном с правом `read:package`:
|
||||
|
||||
```bash
|
||||
docker login gitea.hsrv.site
|
||||
```
|
||||
`.env` не хранится в git (он в `.gitignore`), поэтому обновления репозитория его не трогают.
|
||||
|
||||
---
|
||||
|
||||
## 6. Запуск
|
||||
## 6. Сборка и запуск
|
||||
|
||||
```bash
|
||||
./update.sh 0.1.0
|
||||
./update.sh
|
||||
```
|
||||
|
||||
Скрипт скачает образы, запустит все сервисы и дождётся готовности API (до 2 минут).
|
||||
Скрипт переключает репозиторий на последний релизный тег (например, `v0.1.1`), собирает образы, запускает
|
||||
все сервисы и ждёт готовности API (до 2 минут). Первая сборка занимает 5–15 минут, следующие — быстрее
|
||||
за счёт кэша Docker. Конкретная версия: `./update.sh v0.1.1`.
|
||||
|
||||
> Локальная сборка поддерживается начиная с `v0.1.1`: в теге `v0.1.0` `compose.yaml` ещё ссылается на реестр образов.
|
||||
> Пока `v0.1.1` не вышел, запускайте `./update.sh main`.
|
||||
При первом запуске Caddy сам получит сертификат для `DOMAIN`, обычно за 10–30 секунд.
|
||||
|
||||
Проверка с любого компьютера:
|
||||
@@ -240,13 +247,15 @@ curl -s https://music.example.com/readyz
|
||||
|
||||
## 10. Обновление, бэкапы, удаление
|
||||
|
||||
Обновление (и откат) на любую версию:
|
||||
Обновление до последнего релиза:
|
||||
|
||||
```bash
|
||||
cd /opt/pipu && ./update.sh 0.2.0
|
||||
cd /opt/pipu-music/deploy && ./update.sh
|
||||
```
|
||||
|
||||
Миграции БД применяются автоматически при старте API.
|
||||
Конкретная версия или откат: `./update.sh v0.2.0`. Скрипт делает `git fetch`, переключается на тег,
|
||||
пересобирает образы и перезапускает сервисы; старые образы удаляются. Миграции БД применяются
|
||||
автоматически при старте API.
|
||||
|
||||
Бэкап базы (всё остальное восстанавливается само — см. [deployment.md](deployment.md#бэкапы)):
|
||||
|
||||
@@ -257,7 +266,7 @@ docker compose exec -T postgres pg_dump -U pipu -Fc pipu > /srv/pipu/backups/pip
|
||||
Остановить сервис, сохранив данные:
|
||||
|
||||
```bash
|
||||
cd /opt/pipu && docker compose down
|
||||
cd /opt/pipu-music/deploy && docker compose down
|
||||
```
|
||||
|
||||
---
|
||||
@@ -269,7 +278,10 @@ cd /opt/pipu && docker compose down
|
||||
| Сертификат не выдаётся, браузер ругается на HTTPS | `dig +short music.example.com` указывает на сервер; порт 80 открыт снаружи; `docker compose logs caddy` |
|
||||
| `502 Bad Gateway` | API ещё запускается или упал: `docker compose ps`, `docker compose logs api` |
|
||||
| `/readyz` отвечает `degraded` | Какая зависимость не `ok` — её логи: `docker compose logs postgres` / `redis` |
|
||||
| `update.sh`: «pull access denied» | Неверный `REGISTRY` в `.env` или нужен `docker login gitea.hsrv.site` |
|
||||
| `update.sh`: ошибка `git fetch` | Нет доступа к репозиторию: проверьте SSH-ключ или сохранённый токен (`git fetch` вручную) |
|
||||
| Сборка падает на скачивании зависимостей | Нет интернета или DNS на сервере; повторите `./update.sh` — уже собранные слои берутся из кэша |
|
||||
| Сборка падает: «no space left on device» | Очистите кэш сборки: `docker builder prune` |
|
||||
| `permission denied … docker.sock` | Пользователь не в группе `docker` (шаг 3) или вы не перелогинились |
|
||||
| `storage-agent` не стартует, ошибка про propagation / shared mount | Ещё раз `sudo ./install.sh`; на хосте `findmnt -o TARGET,PROPAGATION /srv/pipu/library` должно показать `shared` |
|
||||
| Android: «Сервер не отвечает» | Тот же адрес открывается в браузере телефона; в адресе нет опечатки; телефон в сети с доступом к серверу |
|
||||
| Android: «Эта версия приложения слишком старая» | Установите APK из последнего релиза |
|
||||
@@ -277,5 +289,5 @@ cd /opt/pipu && docker compose down
|
||||
Логи всех сервисов сразу:
|
||||
|
||||
```bash
|
||||
cd /opt/pipu && docker compose logs -f --tail=100
|
||||
cd /opt/pipu-music/deploy && docker compose logs -f --tail=100
|
||||
```
|
||||
Reference in new issue
Block a user