docs(install): music on a local disk at /mnt/music, repo in /opt/pipu-music
ci / docker (образы собираются — их сервер собирает сам при обновлении) (apps/web/Dockerfile, web, ) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, api, api) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, storage-agent, storage-agent) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/recommender/Dockerfile, recommender, ) (push) Canceled after 0s
ci / mobile (Metro-бандл Android) (push) Canceled after 0s
ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / recommender (push) Canceled after 0s
ci / ts (packages + web) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (apps/web/Dockerfile, web, ) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, api, api) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/api/Dockerfile, storage-agent, storage-agent) (push) Canceled after 0s
ci / docker (образы собираются — их сервер собирает сам при обновлении) (services/recommender/Dockerfile, recommender, ) (push) Canceled after 0s
ci / mobile (Metro-бандл Android) (push) Canceled after 0s
ci / contract (сгенерированный код совпадает с openapi.yaml) (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / recommender (push) Canceled after 0s
ci / ts (packages + web) (push) Canceled after 0s
Add an install step for mounting the music disk via fstab and wire it into the stack: LIBRARY_HOST in .env points at the host folder, compose mounts it as /library-host (read-only for api, nginx and analyzer; writable only for storage-agent), nginx serves it through X-Accel, and install.sh validates the path and records it in .env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
42d64cd49f
commit
38edcd3e0e
7 files changed
+120
-20
No files matched your search
@@ -4,6 +4,9 @@
|
|||||||
# PIPU_VERSION проставляет update.sh по git-тегу — вручную не менять
|
# PIPU_VERSION проставляет update.sh по git-тегу — вручную не менять
|
||||||
PIPU_VERSION=dev
|
PIPU_VERSION=dev
|
||||||
PIPU_DATA=/srv/pipu
|
PIPU_DATA=/srv/pipu
|
||||||
|
# Папка с музыкой на локальном диске сервера (источники type=local), например смонтированный диск.
|
||||||
|
# Пусто — $PIPU_DATA/library-host. NFS-хранилища сюда не относятся: их подключает админка.
|
||||||
|
LIBRARY_HOST=
|
||||||
|
|
||||||
# --- Домен и HTTPS (docs/install-guide.md) ---
|
# --- Домен и HTTPS (docs/install-guide.md) ---
|
||||||
# Вариант А: встроенный Caddy с Let's Encrypt — оставьте строку COMPOSE_FILE и заполните DOMAIN, ACME_EMAIL.
|
# Вариант А: встроенный Caddy с Let's Encrypt — оставьте строку COMPOSE_FILE и заполните DOMAIN, ACME_EMAIL.
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ x-library-ro: &library-ro
|
|||||||
read_only: true
|
read_only: true
|
||||||
bind: { propagation: rslave }
|
bind: { propagation: rslave }
|
||||||
|
|
||||||
|
# Локальная музыка (источники type=local): каталог хоста, например смонтированный диск /mnt/music.
|
||||||
|
# Пишет в него только storage-agent (импорт одобренных загрузок), остальным — только чтение.
|
||||||
|
x-library-host-ro: &library-host-ro
|
||||||
|
type: bind
|
||||||
|
source: ${LIBRARY_HOST:-${PIPU_DATA:-/srv/pipu}/library-host}
|
||||||
|
target: /library-host
|
||||||
|
read_only: true
|
||||||
|
|
||||||
x-restart: &restart
|
x-restart: &restart
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
@@ -31,6 +39,7 @@ services:
|
|||||||
ports: ["${HTTP_PORT:-80}:80"]
|
ports: ["${HTTP_PORT:-80}:80"]
|
||||||
volumes:
|
volumes:
|
||||||
- *library-ro
|
- *library-ro
|
||||||
|
- *library-host-ro
|
||||||
- ${PIPU_DATA:-/srv/pipu}/cache:/cache:ro
|
- ${PIPU_DATA:-/srv/pipu}/cache:/cache:ro
|
||||||
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads:ro
|
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads:ro
|
||||||
depends_on: [api]
|
depends_on: [api]
|
||||||
@@ -48,6 +57,7 @@ services:
|
|||||||
DATABASE_URL: postgres://pipu:${POSTGRES_PASSWORD:?заполните POSTGRES_PASSWORD в .env (sudo ./install.sh)}@postgres:5432/pipu?sslmode=disable
|
DATABASE_URL: postgres://pipu:${POSTGRES_PASSWORD:?заполните POSTGRES_PASSWORD в .env (sudo ./install.sh)}@postgres:5432/pipu?sslmode=disable
|
||||||
volumes:
|
volumes:
|
||||||
- *library-ro
|
- *library-ro
|
||||||
|
- *library-host-ro
|
||||||
- ${PIPU_DATA:-/srv/pipu}/cache:/cache
|
- ${PIPU_DATA:-/srv/pipu}/cache:/cache
|
||||||
- ${PIPU_DATA:-/srv/pipu}/updates:/updates
|
- ${PIPU_DATA:-/srv/pipu}/updates:/updates
|
||||||
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads
|
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads
|
||||||
@@ -75,6 +85,9 @@ services:
|
|||||||
source: ${PIPU_DATA:-/srv/pipu}/library
|
source: ${PIPU_DATA:-/srv/pipu}/library
|
||||||
target: /library
|
target: /library
|
||||||
bind: { propagation: rshared }
|
bind: { propagation: rshared }
|
||||||
|
- type: bind
|
||||||
|
source: ${LIBRARY_HOST:-${PIPU_DATA:-/srv/pipu}/library-host}
|
||||||
|
target: /library-host
|
||||||
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads:ro
|
- ${PIPU_DATA:-/srv/pipu}/uploads:/uploads:ro
|
||||||
|
|
||||||
recommender:
|
recommender:
|
||||||
@@ -102,6 +115,7 @@ services:
|
|||||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||||
volumes:
|
volumes:
|
||||||
- *library-ro
|
- *library-ro
|
||||||
|
- *library-host-ro
|
||||||
- ${PIPU_DATA:-/srv/pipu}/models:/models
|
- ${PIPU_DATA:-/srv/pipu}/models:/models
|
||||||
deploy: { resources: { limits: { cpus: "4" } } }
|
deploy: { resources: { limits: { cpus: "4" } } }
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
+20
-1
@@ -17,6 +17,16 @@ mkdir -p "$DATA"/{library,library-host,cache/transcode,cache/covers,postgres,mei
|
|||||||
chown 65532:65532 "$DATA"/{cache,cache/transcode,cache/covers,updates,uploads}
|
chown 65532:65532 "$DATA"/{cache,cache/transcode,cache/covers,updates,uploads}
|
||||||
chown 10001:10001 "$DATA/models"
|
chown 10001:10001 "$DATA/models"
|
||||||
|
|
||||||
|
# Папка с локальной музыкой: sudo LIBRARY_HOST=/mnt/music ./install.sh (или LIBRARY_HOST в .env)
|
||||||
|
LIBRARY_HOST="${LIBRARY_HOST:-$( [ -f .env ] && sed -n 's/^LIBRARY_HOST=//p' .env || true )}"
|
||||||
|
if [ -n "$LIBRARY_HOST" ]; then
|
||||||
|
if [ ! -d "$LIBRARY_HOST" ]; then
|
||||||
|
echo "LIBRARY_HOST=$LIBRARY_HOST: каталога нет — смонтируйте диск с музыкой (docs/install-guide.md, шаг 4)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
findmnt -n --target "$LIBRARY_HOST" -o TARGET,SOURCE | sed 's/^/→ музыка: /'
|
||||||
|
fi
|
||||||
|
|
||||||
# storage-agent монтирует NFS внутрь $DATA/library; чтобы точки монтирования видели другие контейнеры,
|
# storage-agent монтирует NFS внутрь $DATA/library; чтобы точки монтирования видели другие контейнеры,
|
||||||
# каталог должен быть отдельной точкой монтирования с shared propagation.
|
# каталог должен быть отдельной точкой монтирования с shared propagation.
|
||||||
if ! findmnt -n "$DATA/library" >/dev/null 2>&1; then
|
if ! findmnt -n "$DATA/library" >/dev/null 2>&1; then
|
||||||
@@ -50,10 +60,19 @@ secret() { head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 40; }
|
|||||||
if [ ! -f .env ]; then
|
if [ ! -f .env ]; then
|
||||||
echo "→ .env из .env.example"
|
echo "→ .env из .env.example"
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(secret)|; s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(secret)|; s|^INTERNAL_TOKEN=.*|INTERNAL_TOKEN=$(secret)|; s|^PIPU_DATA=.*|PIPU_DATA=$DATA|" .env
|
sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(secret)|; s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(secret)|; s|^INTERNAL_TOKEN=.*|INTERNAL_TOKEN=$(secret)|; s|^PIPU_DATA=.*|PIPU_DATA=$DATA|; s|^LIBRARY_HOST=.*|LIBRARY_HOST=$LIBRARY_HOST|" .env
|
||||||
chmod 600 .env
|
chmod 600 .env
|
||||||
chown "$OWNER" .env
|
chown "$OWNER" .env
|
||||||
echo " Заполните в .env: DOMAIN и ACME_EMAIL (или настройте свой прокси — docs/install-guide.md)"
|
echo " Заполните в .env: DOMAIN и ACME_EMAIL (или настройте свой прокси — docs/install-guide.md)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# LIBRARY_HOST, переданный при повторном запуске, попадает и в уже существующий .env
|
||||||
|
if [ -n "$LIBRARY_HOST" ]; then
|
||||||
|
if grep -q '^LIBRARY_HOST=' .env; then
|
||||||
|
sed -i "s|^LIBRARY_HOST=.*|LIBRARY_HOST=$LIBRARY_HOST|" .env
|
||||||
|
else
|
||||||
|
echo "LIBRARY_HOST=$LIBRARY_HOST" >> .env
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Готово. Сборка и запуск последнего релиза: ./update.sh"
|
echo "Готово. Сборка и запуск последнего релиза: ./update.sh"
|
||||||
@@ -48,6 +48,7 @@ server {
|
|||||||
|
|
||||||
# Аудио и обложки отдаёт nginx по заголовку X-Accel-Redirect от api (docs/playback.md).
|
# Аудио и обложки отдаёт nginx по заголовку X-Accel-Redirect от api (docs/playback.md).
|
||||||
location /_internal/library/ { internal; alias /library/; sendfile on; aio threads; }
|
location /_internal/library/ { internal; alias /library/; sendfile on; aio threads; }
|
||||||
|
location /_internal/library-host/ { internal; alias /library-host/; sendfile on; aio threads; }
|
||||||
location /_internal/cache/ { internal; alias /cache/transcode/; sendfile on; }
|
location /_internal/cache/ { internal; alias /cache/transcode/; sendfile on; }
|
||||||
location /_internal/covers/ { internal; alias /cache/covers/; expires 30d; }
|
location /_internal/covers/ { internal; alias /cache/covers/; expires 30d; }
|
||||||
location /_internal/uploads/ { internal; alias /uploads/; sendfile on; }
|
location /_internal/uploads/ { internal; alias /uploads/; sendfile on; }
|
||||||
|
|||||||
+5
-1
@@ -15,7 +15,7 @@
|
|||||||
```
|
```
|
||||||
/srv/pipu/
|
/srv/pipu/
|
||||||
├── library/ # точки монтирования источников (storage-agent, rshared)
|
├── library/ # точки монтирования источников (storage-agent, rshared)
|
||||||
├── library-host/ # опционально: заранее смонтированные папки для type=local
|
├── library-host/ # папка для type=local по умолчанию; обычно вместо неё LIBRARY_HOST=/mnt/music
|
||||||
├── cache/
|
├── cache/
|
||||||
│ ├── transcode/
|
│ ├── transcode/
|
||||||
│ └── covers/
|
│ └── covers/
|
||||||
@@ -29,6 +29,10 @@
|
|||||||
└── caddy/ # сертификаты Let's Encrypt (если используется compose.tls.yaml)
|
└── caddy/ # сертификаты Let's Encrypt (если используется compose.tls.yaml)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Музыка на локальном диске сервера подключается через `LIBRARY_HOST` в `.env` (например, `/mnt/music`):
|
||||||
|
каталог хоста монтируется в `api`, `nginx` и `analyzer` только на чтение, в `storage-agent` — на запись
|
||||||
|
(импорт одобренных загрузок), внутри контейнеров он виден как `/library-host`.
|
||||||
|
|
||||||
Перед первым запуском: `mkdir -p /srv/pipu/library && mount --bind /srv/pipu/library /srv/pipu/library && mount --make-rshared /srv/pipu/library`
|
Перед первым запуском: `mkdir -p /srv/pipu/library && mount --bind /srv/pipu/library /srv/pipu/library && mount --make-rshared /srv/pipu/library`
|
||||||
(делает `deploy/install.sh`, плюс systemd-unit для повторения после перезагрузки).
|
(делает `deploy/install.sh`, плюс systemd-unit для повторения после перезагрузки).
|
||||||
|
|
||||||
|
|||||||
+76
-17
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
В примерах:
|
В примерах:
|
||||||
- домен — `music.example.com`, замените на свой;
|
- домен — `music.example.com`, замените на свой;
|
||||||
- репозиторий — `gitea.hsrv.site/mrleo1nid/pipu-music`;
|
- репозиторий — `gitea.hsrv.site/mrleo1nid/pipu-music`, клонируется в `/opt/pipu-music`;
|
||||||
- каталог установки — `/opt/pipu-music`.
|
- диск с музыкой смонтирован в `/mnt/music`;
|
||||||
|
- данные сервиса (БД, кэши, сертификаты) — в `/srv/pipu`.
|
||||||
|
|
||||||
Готовые Docker-образы не публикуются: сервер клонирует репозиторий и собирает образы сам
|
Готовые Docker-образы не публикуются: сервер клонирует репозиторий и собирает образы сам
|
||||||
(`docker compose build`). Релизы в Gitea содержат только APK для Android.
|
(`docker compose build`). Релизы в Gitea содержат только APK для Android.
|
||||||
@@ -22,11 +23,11 @@
|
|||||||
|
|
||||||
| Что | Требование |
|
| Что | Требование |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Сервер | Linux x86_64 (Debian 12 / Ubuntu 22.04+), 4+ ядра, 8+ ГБ RAM, 30+ ГБ на диске (система, образы, кэш сборки, данные) |
|
| Сервер | Linux x86_64 (Debian 12 / Ubuntu 22.04+), 4+ ядра, 8+ ГБ RAM, 30+ ГБ на системном диске (система, образы, кэш сборки, данные) |
|
||||||
| Доступ | root или пользователь с `sudo` |
|
| Доступ | root или пользователь с `sudo` |
|
||||||
| Домен | Поддомен, которым вы управляете, например `music.example.com` |
|
| Домен | Поддомен, которым вы управляете, например `music.example.com` |
|
||||||
| Сеть | Входящие **80/tcp** и **443/tcp** (+ **443/udp** для HTTP/3) из интернета на сервер |
|
| Сеть | Входящие **80/tcp** и **443/tcp** (+ **443/udp** для HTTP/3) из интернета на сервер |
|
||||||
| Музыка | NFS-сервер с библиотекой (подключается позже из админки) |
|
| Музыка | Отдельный диск с библиотекой, подключённый к серверу (шаг 4). NFS-хранилища можно добавить позже из админки |
|
||||||
| Интернет на сервере | Нужен при сборке: скачиваются базовые образы и зависимости Go / npm / Python |
|
| Интернет на сервере | Нужен при сборке: скачиваются базовые образы и зависимости Go / npm / Python |
|
||||||
| Gitea | Доступ к репозиторию на чтение (если он приватный — токен или SSH-ключ) |
|
| Gitea | Доступ к репозиторию на чтение (если он приватный — токен или SSH-ключ) |
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ dig +short music.example.com
|
|||||||
```
|
```
|
||||||
|
|
||||||
> Сертификат Let's Encrypt выдаётся, только когда домен уже указывает на сервер и порт 80 доступен из интернета.
|
> Сертификат Let's Encrypt выдаётся, только когда домен уже указывает на сервер и порт 80 доступен из интернета.
|
||||||
> Не запускайте шаг 6, пока эта проверка не проходит.
|
> Не запускайте шаг 7, пока эта проверка не проходит.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -86,7 +87,51 @@ sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw allow 443/udp
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Клонирование репозитория
|
## 4. Диск с музыкой
|
||||||
|
|
||||||
|
Музыка лежит на отдельном диске, смонтированном в `/mnt/music`. Если диск уже смонтирован — проверьте его
|
||||||
|
командой из конца шага и переходите к шагу 5.
|
||||||
|
|
||||||
|
Найдите диск и его UUID (раздел с музыкой — например, `/dev/sdb1`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsblk -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте точку монтирования:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /mnt/music
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавьте в `/etc/fstab` строку (подставьте свой UUID и файловую систему из вывода `lsblk -f`):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
UUID=1234abcd-0000-0000-0000-000000000000 /mnt/music ext4 defaults,nofail,noatime 0 2
|
||||||
|
```
|
||||||
|
|
||||||
|
`nofail` нужен, чтобы сервер загружался, даже если диск не подключён. Смонтируйте и проверьте:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mount -a && findmnt /mnt/music && ls /mnt/music | head
|
||||||
|
```
|
||||||
|
|
||||||
|
Сервисы Pipu работают в контейнерах не от root, поэтому музыка должна быть доступна на чтение всем:
|
||||||
|
файлы — `644`, каталоги — `755`. Если раньше права были закрытыми:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chmod -R a+rX /mnt/music
|
||||||
|
```
|
||||||
|
|
||||||
|
> Для дисков с NTFS / exFAT права задаются опциями монтирования, а не `chmod`: добавьте в fstab
|
||||||
|
> `uid=0,gid=0,umask=022` вместо `defaults`.
|
||||||
|
|
||||||
|
Pipu только читает этот диск. Записывать в него будет лишь импорт одобренных треков из очереди на добавление,
|
||||||
|
и только если в админке разрешить это для хранилища ([uploads.md](uploads.md)).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Клонирование репозитория
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo mkdir -p /opt/pipu-music && sudo chown "$USER" /opt/pipu-music
|
sudo mkdir -p /opt/pipu-music && sudo chown "$USER" /opt/pipu-music
|
||||||
@@ -104,16 +149,18 @@ git clone https://gitea.hsrv.site/mrleo1nid/pipu-music.git /opt/pipu-music && cd
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Подготовка сервера
|
## 6. Подготовка сервера
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo ./install.sh
|
sudo LIBRARY_HOST=/mnt/music ./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Скрипт:
|
Скрипт:
|
||||||
- создаёт каталоги данных в `/srv/pipu` (БД, кэши, загрузки, сертификаты);
|
- создаёт каталоги данных в `/srv/pipu` (БД, кэши, загрузки, сертификаты);
|
||||||
- делает `/srv/pipu/library` точкой монтирования с shared propagation, чтобы NFS-хранилища, которые потом
|
- делает `/srv/pipu/library` точкой монтирования с shared propagation, чтобы NFS-хранилища, которые потом
|
||||||
подключит админ, были видны всем контейнерам, и ставит systemd-юнит, повторяющий это после перезагрузки;
|
подключит админ, были видны всем контейнерам, и ставит systemd-юнит, повторяющий это после перезагрузки;
|
||||||
|
- проверяет, что `/mnt/music` существует, и записывает его в `.env` как `LIBRARY_HOST` — эту папку получат
|
||||||
|
контейнеры `api`, `nginx` и `analyzer` (внутри они видят её как `/library-host`);
|
||||||
- создаёт `.env` со случайными паролями БД, ключом поиска и межсервисным токеном.
|
- создаёт `.env` со случайными паролями БД, ключом поиска и межсервисным токеном.
|
||||||
|
|
||||||
Заполните в `/opt/pipu-music/deploy/.env`:
|
Заполните в `/opt/pipu-music/deploy/.env`:
|
||||||
@@ -124,6 +171,14 @@ DOMAIN=music.example.com
|
|||||||
ACME_EMAIL=you@example.com
|
ACME_EMAIL=you@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Проверьте, что там же стоит путь к музыке (его вписал `install.sh`):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
LIBRARY_HOST=/mnt/music
|
||||||
|
```
|
||||||
|
|
||||||
|
Если диск смонтирован в другое место — поправьте путь здесь и перезапустите сервисы (`./update.sh`).
|
||||||
|
|
||||||
`ACME_EMAIL` — адрес, на который Let's Encrypt пишет, если с сертификатом что-то не так.
|
`ACME_EMAIL` — адрес, на который Let's Encrypt пишет, если с сертификатом что-то не так.
|
||||||
Остальные значения менять не нужно; `PIPU_VERSION` проставляет `update.sh`.
|
Остальные значения менять не нужно; `PIPU_VERSION` проставляет `update.sh`.
|
||||||
|
|
||||||
@@ -131,7 +186,7 @@ ACME_EMAIL=you@example.com
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Сборка и запуск
|
## 7. Сборка и запуск
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./update.sh
|
./update.sh
|
||||||
@@ -161,7 +216,7 @@ curl -s https://music.example.com/readyz
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Веб-клиент
|
## 8. Веб-клиент
|
||||||
|
|
||||||
Откройте `https://music.example.com` в браузере.
|
Откройте `https://music.example.com` в браузере.
|
||||||
|
|
||||||
@@ -176,12 +231,14 @@ curl -s https://music.example.com/readyz
|
|||||||
Сразу после входа приложение попросит сменить логин и пароль администратора
|
Сразу после входа приложение попросит сменить логин и пароль администратора
|
||||||
([auth-and-roles.md](auth-and-roles.md#первый-запуск-bootstrap)). Чтобы задать пароль заранее, впишите
|
([auth-and-roles.md](auth-and-roles.md#первый-запуск-bootstrap)). Чтобы задать пароль заранее, впишите
|
||||||
`BOOTSTRAP_ADMIN_PASSWORD` в `.env` **до** первого запуска.
|
`BOOTSTRAP_ADMIN_PASSWORD` в `.env` **до** первого запуска.
|
||||||
- **С версии 0.3 (M2):** Админка → Хранилища → «Добавить хранилище» → адрес NFS-сервера и путь экспорта
|
- **С версии 0.3 (M2):** Админка → Хранилища → «Добавить хранилище» → тип «Локальная папка» → выберите
|
||||||
→ «Проверить» → шаблоны путей → «Сохранить и пересканировать» ([library-and-storage.md](library-and-storage.md)).
|
подпапку на диске `/mnt/music` (в списке она видна как `/library-host/...`) → «Проверить» → шаблоны путей
|
||||||
|
→ «Сохранить и пересканировать» ([library-and-storage.md](library-and-storage.md)).
|
||||||
|
Там же можно добавить NFS-хранилище: адрес сервера и путь экспорта.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Android-приложение
|
## 9. Android-приложение
|
||||||
|
|
||||||
1. На телефоне откройте страницу релизов
|
1. На телефоне откройте страницу релизов
|
||||||
`https://gitea.hsrv.site/mrleo1nid/pipu-music/releases` и скачайте `pipu-music-<версия>.apk`.
|
`https://gitea.hsrv.site/mrleo1nid/pipu-music/releases` и скачайте `pipu-music-<версия>.apk`.
|
||||||
@@ -201,7 +258,7 @@ curl -s https://music.example.com/readyz
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Вариант: свой reverse proxy вместо Caddy
|
## 10. Вариант: свой reverse proxy вместо Caddy
|
||||||
|
|
||||||
Если на сервере уже есть Traefik, Nginx Proxy Manager или свой nginx с сертификатами:
|
Если на сервере уже есть Traefik, Nginx Proxy Manager или свой nginx с сертификатами:
|
||||||
|
|
||||||
@@ -238,14 +295,14 @@ curl -s https://music.example.com/readyz
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Запуск и проверки — как в шагах 6–8.
|
3. Запуск и проверки — как в шагах 7–9.
|
||||||
|
|
||||||
Если прокси работает на другой машине, укажите в `HTTP_PORT` внутренний адрес сервера (`192.168.1.10:8081`) и
|
Если прокси работает на другой машине, укажите в `HTTP_PORT` внутренний адрес сервера (`192.168.1.10:8081`) и
|
||||||
закройте этот порт от интернета файрволом.
|
закройте этот порт от интернета файрволом.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Обновление, бэкапы, удаление
|
## 11. Обновление, бэкапы, удаление
|
||||||
|
|
||||||
Обновление до последнего релиза:
|
Обновление до последнего релиза:
|
||||||
|
|
||||||
@@ -271,7 +328,7 @@ cd /opt/pipu-music/deploy && docker compose down
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. Если что-то не работает
|
## 12. Если что-то не работает
|
||||||
|
|
||||||
| Симптом | Что проверить |
|
| Симптом | Что проверить |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -282,6 +339,8 @@ cd /opt/pipu-music/deploy && docker compose down
|
|||||||
| Сборка падает на скачивании зависимостей | Нет интернета или DNS на сервере; повторите `./update.sh` — уже собранные слои берутся из кэша |
|
| Сборка падает на скачивании зависимостей | Нет интернета или DNS на сервере; повторите `./update.sh` — уже собранные слои берутся из кэша |
|
||||||
| Сборка падает: «no space left on device» | Очистите кэш сборки: `docker builder prune` |
|
| Сборка падает: «no space left on device» | Очистите кэш сборки: `docker builder prune` |
|
||||||
| `permission denied … docker.sock` | Пользователь не в группе `docker` (шаг 3) или вы не перелогинились |
|
| `permission denied … docker.sock` | Пользователь не в группе `docker` (шаг 3) или вы не перелогинились |
|
||||||
|
| Сервисы не стартуют: `bind source path does not exist: /mnt/music` | Диск не смонтирован: `findmnt /mnt/music`, `sudo mount -a`; путь в `LIBRARY_HOST` в `.env` |
|
||||||
|
| Хранилище «Локальная папка» пустое или ошибка доступа | Диск смонтирован (`ls /mnt/music`); права на чтение для всех — `sudo chmod -R a+rX /mnt/music` (шаг 4) |
|
||||||
| `storage-agent` не стартует, ошибка про propagation / shared mount | Ещё раз `sudo ./install.sh`; на хосте `findmnt -o TARGET,PROPAGATION /srv/pipu/library` должно показать `shared` |
|
| `storage-agent` не стартует, ошибка про propagation / shared mount | Ещё раз `sudo ./install.sh`; на хосте `findmnt -o TARGET,PROPAGATION /srv/pipu/library` должно показать `shared` |
|
||||||
| Android: «Сервер не отвечает» | Тот же адрес открывается в браузере телефона; в адресе нет опечатки; телефон в сети с доступом к серверу |
|
| Android: «Сервер не отвечает» | Тот же адрес открывается в браузере телефона; в адресе нет опечатки; телефон в сети с доступом к серверу |
|
||||||
| Android: «Эта версия приложения слишком старая» | Установите APK из последнего релиза |
|
| Android: «Эта версия приложения слишком старая» | Установите APK из последнего релиза |
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
| Тип | Как подключается |
|
| Тип | Как подключается |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `nfs` | Админ указывает `server`, `export`, опции. `storage-agent` выполняет `mount -t nfs -o <opts> server:export /library/<id>`. |
|
| `nfs` | Админ указывает `server`, `export`, опции. `storage-agent` выполняет `mount -t nfs -o <opts> server:export /library/<id>`. |
|
||||||
| `local` | Папка, уже смонтированная на хосте в `/srv/pipu/library-host` (например, через fstab). Админ выбирает подпапку. Нужен как запасной путь и для dev. |
|
| `local` | Папка на диске сервера, заранее смонтированная на хосте (например, диск `/mnt/music` через fstab) и указанная в `LIBRARY_HOST`. В контейнерах видна как `/library-host`; админ выбирает подпапку. |
|
||||||
|
|
||||||
### Монтирование (storage-agent)
|
### Монтирование (storage-agent)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user