Files
pipu-music/docs/install-guide.md
T
mrleo1nidandClaude Opus 5.5 1633b28c1a
ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 47s
ci / api (push) Successful in 53s
ci / recommender (push) Successful in 37s
ci / ts (packages + web) (push) Successful in 38s
ci / mobile (Metro-бандл Android) (push) Successful in 52s
docs(deploy): add install guide for a domain with HTTPS
- docs/install-guide.md: step-by-step server setup (DNS, Docker, install.sh,
  .env, launch, checks), web and Android client setup, own reverse proxy
  variant, updates, backups and troubleshooting
- deploy/compose.tls.yaml + Caddyfile: optional Caddy with automatic
  Let's Encrypt in front of nginx (enabled via COMPOSE_FILE in .env)
- nginx: honour X-Forwarded-Proto/For from private networks
- .env.example: DOMAIN, ACME_EMAIL, COMPOSE_FILE, bootstrap admin vars
- install.sh: create caddy data dirs; release.yml: ship TLS files as assets
- deployment.md, docs index and README link to the guide

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 00:03:26 +03:00

282 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Установка сервера и подключение приложений
Пошаговая инструкция: от чистого Linux-сервера до работающего Pipu Music на своём домене
с HTTPS, плюс подключение веб- и Android-клиента. Справочник по устройству развёртывания —
[deployment.md](deployment.md).
В примерах:
- домен — `music.example.com`, замените на свой;
- репозиторий — `gitea.hsrv.site/mrleo1nid/pipu-music`;
- реестр образов — `gitea.hsrv.site/mrleo1nid`.
> **Что умеет текущая версия.** В `v0.1.0` (этап M0) работают развёртывание, HTTPS и проверка связи
> клиентов с сервером. Вход, библиотека и плеер появятся в следующих версиях
> (см. [roadmap.md](roadmap.md)). Шаги, которые зависят от версии, помечены.
---
## 1. Что нужно заранее
| Что | Требование |
|---|---|
| Сервер | Linux x86_64 (Debian 12 / Ubuntu 22.04+), 4+ ядра, 8+ ГБ RAM, 20+ ГБ на диске под систему и кэши |
| Доступ | root или пользователь с `sudo` |
| Домен | Поддомен, которым вы управляете, например `music.example.com` |
| Сеть | Входящие **80/tcp** и **443/tcp** (+ **443/udp** для HTTP/3) из интернета на сервер |
| Музыка | NFS-сервер с библиотекой (подключается позже из админки) |
| Gitea | Аккаунт с доступом к репозиторию, если пакеты и релизы приватные |
---
## 2. DNS
Создайте у регистратора или в DNS-панели запись:
| Тип | Имя | Значение |
|---|---|---|
| `A` | `music` | публичный IPv4 сервера |
| `AAAA` | `music` | публичный IPv6 (если есть; если нет — запись не создавайте) |
Если сервер стоит дома за роутером, пробросьте на роутере порты 80 и 443 на внутренний IP сервера.
Проверка — команда должна вернуть IP вашего сервера:
```bash
dig +short music.example.com
```
> Сертификат Let's Encrypt выдаётся, только когда домен уже указывает на сервер и порт 80 доступен из интернета.
> Не запускайте шаг 6, пока эта проверка не проходит.
---
## 3. Docker
```bash
curl -fsSL https://get.docker.com | sudo sh
```
Проверьте, что есть Docker Compose v2.24 или новее (нужен для `compose.tls.yaml`):
```bash
docker compose version
```
Откройте порты в файрволе, если он включён (пример для `ufw`):
```bash
sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw allow 443/udp
```
---
## 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
```
```bash
chmod +x install.sh update.sh
```
> Если репозиторий приватный, добавьте к `curl` заголовок с токеном Gitea (право `read:repository`):
> `-H "Authorization: token <ТОКЕН>"`.
---
## 5. Подготовка сервера
```bash
sudo ./install.sh
```
Скрипт:
- создаёт каталоги данных в `/srv/pipu` (БД, кэши, загрузки, сертификаты);
- делает `/srv/pipu/library` точкой монтирования с shared propagation, чтобы NFS-хранилища, которые потом
подключит админ, были видны всем контейнерам, и ставит systemd-юнит, повторяющий это после перезагрузки;
- создаёт `.env` со случайными паролями БД, ключом поиска и межсервисным токеном.
Заполните в `/opt/pipu/.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 пишет, если с сертификатом что-то не так.
Остальные значения менять не нужно.
Если образы в Gitea приватные, войдите в реестр токеном с правом `read:package`:
```bash
docker login gitea.hsrv.site
```
---
## 6. Запуск
```bash
./update.sh 0.1.0
```
Скрипт скачает образы, запустит все сервисы и дождётся готовности API (до 2 минут).
При первом запуске Caddy сам получит сертификат для `DOMAIN`, обычно за 10–30 секунд.
Проверка с любого компьютера:
```bash
curl -s https://music.example.com/api/v1/server-info
```
Ожидаемый ответ: `{"name":"pipu-music","version":"0.1.0",...}`. Проверка всех зависимостей:
```bash
curl -s https://music.example.com/readyz
```
Должно вернуться `"status":"ok"` и `ok` для `postgres` и `redis`.
---
## 7. Веб-клиент
Откройте `https://music.example.com` в браузере.
- **v0.1.0:** карточка «Сервер 0.1.0 на связи» и переключатель языка RU / EN.
- **С версии 0.2 (M1):** экран входа. Первый вход — логин `admin` и пароль, который сервер один раз
выводит в лог при первом запуске:
```bash
docker compose logs api | grep -i bootstrap
```
Сразу после входа приложение попросит сменить логин и пароль администратора
([auth-and-roles.md](auth-and-roles.md#первый-запуск-bootstrap)). Чтобы задать пароль заранее, впишите
`BOOTSTRAP_ADMIN_PASSWORD` в `.env` **до** первого запуска.
- **С версии 0.3 (M2):** Админка → Хранилища → «Добавить хранилище» → адрес NFS-сервера и путь экспорта
→ «Проверить» → шаблоны путей → «Сохранить и пересканировать» ([library-and-storage.md](library-and-storage.md)).
---
## 8. Android-приложение
1. На телефоне откройте страницу релизов
`https://gitea.hsrv.site/mrleo1nid/pipu-music/releases` и скачайте `pipu-music-<версия>.apk`.
2. Откройте файл. Android попросит разрешить установку из этого источника (браузера или файлового менеджера) —
разрешите и вернитесь к установке.
3. Запустите **Pipu Music**, на экране подключения введите адрес сервера: `music.example.com`
(`https://` подставится сам) → «Проверить».
4. Ожидаемый результат — «Сервер 0.1.0 на связи». Если версия приложения слишком старая для сервера,
приложение попросит обновиться.
Дальше приложение обновляется само: с версии M5 оно проверяет новые релизы через ваш сервер
и предлагает обновиться ([mobile.md](mobile.md#самообновление)). Для этого в `.env` сервера нужно заполнить
`GITEA_URL`, `GITEA_REPO` и `GITEA_TOKEN` (токен только на чтение).
> Приложению нужен настоящий сертификат. С самоподписанным сертификатом и голым IP-адресом подключиться не получится.
> Поэтому нужен домен с Let's Encrypt, как в этой инструкции.
---
## 9. Вариант: свой reverse proxy вместо Caddy
Если на сервере уже есть Traefik, Nginx Proxy Manager или свой nginx с сертификатами:
1. В `.env` закомментируйте `COMPOSE_FILE` и задайте порт, на котором Pipu будет слушать только локально:
```ini
#COMPOSE_FILE=compose.yaml:compose.tls.yaml
HTTP_PORT=127.0.0.1:8081
```
2. Направьте прокси для `music.example.com` на `http://127.0.0.1:8081` с такими настройками:
- передавать заголовки `Host`, `X-Forwarded-For`, `X-Forwarded-Proto`;
- лимит тела запроса не меньше **16 МБ** (загрузка треков идёт чанками по 8 МБ);
- **без буферизации ответов** (стриминг аудио), длинные таймауты чтения (≥ 1 ч).
Пример для nginx:
```nginx
server {
listen 443 ssl http2;
server_name music.example.com;
# ssl_certificate / ssl_certificate_key — как у остальных ваших сайтов
client_max_body_size 16m;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_read_timeout 1h;
}
}
```
3. Запуск и проверки — как в шагах 6–8.
Если прокси работает на другой машине, укажите в `HTTP_PORT` внутренний адрес сервера (`192.168.1.10:8081`) и
закройте этот порт от интернета файрволом.
---
## 10. Обновление, бэкапы, удаление
Обновление (и откат) на любую версию:
```bash
cd /opt/pipu && ./update.sh 0.2.0
```
Миграции БД применяются автоматически при старте API.
Бэкап базы (всё остальное восстанавливается само — см. [deployment.md](deployment.md#бэкапы)):
```bash
docker compose exec -T postgres pg_dump -U pipu -Fc pipu > /srv/pipu/backups/pipu-$(date +%F).dump
```
Остановить сервис, сохранив данные:
```bash
cd /opt/pipu && docker compose down
```
---
## 11. Если что-то не работает
| Симптом | Что проверить |
|---|---|
| Сертификат не выдаётся, браузер ругается на 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` |
| `storage-agent` не стартует, ошибка про propagation / shared mount | Ещё раз `sudo ./install.sh`; на хосте `findmnt -o TARGET,PROPAGATION /srv/pipu/library` должно показать `shared` |
| Android: «Сервер не отвечает» | Тот же адрес открывается в браузере телефона; в адресе нет опечатки; телефон в сети с доступом к серверу |
| Android: «Эта версия приложения слишком старая» | Установите APK из последнего релиза |
Логи всех сервисов сразу:
```bash
cd /opt/pipu && docker compose logs -f --tail=100
```