238 lines
11 KiB
Markdown
238 lines
11 KiB
Markdown
# Подготовка диска под медиахранилище (tvvm)
|
||
|
||
Runbook: разметка, форматирование и монтирование диска `sdb` (700G) под хранилище TeleWave.
|
||
Выполняется **один раз** на сервере `tvvm` перед запуском фичи медиа. Все команды — от root
|
||
(`sudo -i` или с `sudo` перед каждой).
|
||
|
||
> ⚠️ Команды разметки **уничтожают данные** на целевом диске. Диск `sdb` сейчас пустой (нет
|
||
> разделов), но каждый шаг ниже содержит проверку — не пропускайте их.
|
||
|
||
Итог: раздел `sdb1` (ext4) смонтирован в `/srv/telewave/media`, внутри созданы рабочие каталоги,
|
||
запись из контейнера (работает под непривилегированным uid 1654) возможна.
|
||
|
||
---
|
||
|
||
## 0. Проверить, что это тот самый диск
|
||
|
||
```bash
|
||
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,FSTYPE /dev/sdb
|
||
```
|
||
|
||
Ожидается: `sdb` размером `700G`, тип `disk`, **без разделов и без точек монтирования**. Убедитесь
|
||
дополнительно, что на диске нет файловой системы и подписей:
|
||
|
||
```bash
|
||
sudo wipefs -n /dev/sdb # -n = «сухой прогон», ничего не меняет
|
||
```
|
||
|
||
Если вывод пустой — диск чист, продолжаем. Если что-то нашлось (следы старой ФС/RAID) —
|
||
**остановитесь** и разберитесь, что это, прежде чем идти дальше.
|
||
|
||
---
|
||
|
||
## 1. Создать таблицу разделов и один раздел
|
||
|
||
GPT + один раздел на весь диск:
|
||
|
||
```bash
|
||
sudo parted -s /dev/sdb mklabel gpt
|
||
sudo parted -s -a optimal /dev/sdb mkpart primary ext4 0% 100%
|
||
sudo partprobe /dev/sdb
|
||
lsblk /dev/sdb
|
||
```
|
||
|
||
Должен появиться `sdb1` размером ~700G.
|
||
|
||
---
|
||
|
||
## 2. Отформатировать в ext4
|
||
|
||
`-m 1` уменьшает резерв под root с 5% до 1% (на диске данных резерв в 35 ГБ не нужен), `-L` даёт
|
||
метку тома:
|
||
|
||
```bash
|
||
sudo mkfs.ext4 -m 1 -L telewave-media /dev/sdb1
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Создать точку монтирования
|
||
|
||
```bash
|
||
sudo mkdir -p /srv/telewave/media
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Прописать в /etc/fstab (монтирование по UUID)
|
||
|
||
Монтируем по UUID, а не по имени `sdb1` — имя может измениться при добавлении дисков. Узнать UUID:
|
||
|
||
```bash
|
||
sudo blkid /dev/sdb1
|
||
```
|
||
|
||
Скопируйте значение `UUID="..."` и добавьте строку в `/etc/fstab` (подставьте свой UUID):
|
||
|
||
```
|
||
UUID=ВАШ-UUID /srv/telewave/media ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 2
|
||
```
|
||
|
||
Пояснения к опциям:
|
||
- `noatime` — не обновлять время доступа при чтении сегментов; заметно снижает лишние записи при
|
||
раздаче видео.
|
||
- `nofail` — если диск не подключился, система всё равно загрузится (приложение просто не сможет
|
||
писать, а не «висит» на загрузке).
|
||
- `x-systemd.device-timeout=10` — не ждать диск дольше 10с при старте.
|
||
|
||
Проверить, что fstab корректен, и смонтировать:
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo mount -a
|
||
findmnt /srv/telewave/media
|
||
```
|
||
|
||
`findmnt` должен показать смонтированный `ext4` на `/dev/sdb1`. **Ошибка на этом шаге лучше, чем
|
||
на следующей перезагрузке** — если `mount -a` ругается, чините fstab сейчас.
|
||
|
||
---
|
||
|
||
## 5. Рабочие каталоги и права
|
||
|
||
Создать структуру, ожидаемую приложением:
|
||
|
||
```bash
|
||
sudo mkdir -p /srv/telewave/media/{inbox,manual,uploads,originals,assets}
|
||
```
|
||
|
||
**Владелец.** Контейнер работает под непривилегированным пользователем `app` образа aspnet —
|
||
**uid/gid 1654** (`USER $APP_UID` в Dockerfile). Bind-mount пробрасывает права хоста внутрь как
|
||
есть, никакого маппинга uid не происходит: контейнер увидит ровно те номера, что стоят на хосте.
|
||
Значит, владельцем хранилища должен быть 1654.
|
||
|
||
Имени `app` на хосте нет — заводим группу с этим gid, чтобы права были читаемыми в `ls` и чтобы
|
||
в неё можно было добавить себя:
|
||
|
||
```bash
|
||
sudo groupadd -g 1654 telewave # «уже существует» — не ошибка, идём дальше
|
||
sudo usermod -aG telewave "$USER" # чтобы класть файлы в inbox/manual под собой
|
||
```
|
||
|
||
> Членство в группе применяется **только к новым сессиям**: перелогиньтесь (или `newgrp telewave`),
|
||
> иначе следующая команда отработает, а записать файл вы всё равно не сможете. Проверка — `id`
|
||
> должен показать `telewave` в списке групп.
|
||
|
||
Теперь владелец и базовые права:
|
||
|
||
```bash
|
||
sudo chown -R 1654:1654 /srv/telewave/media
|
||
sudo chmod -R 750 /srv/telewave/media
|
||
```
|
||
|
||
Два каталога наполняете вы, а не приложение:
|
||
|
||
- `inbox/` — разбирается сканером автоматически: файл с допустимым расширением и стабильным
|
||
размером регистрируется сам и уходит в обработку;
|
||
- `manual/` — **ручной разбор**: сканер сюда не заглядывает. Файлы видны в админке
|
||
(Медиа → «Из папки manual»), выбираются галочками и сразу привязываются к шоу. Импортированные
|
||
файлы уходят из каталога так же, как из `inbox/`.
|
||
|
||
Их открываем группе на запись, плюс setgid (`2` в начале режима) — чтобы файлы, положенные вами по
|
||
SFTP/rsync, наследовали группу `telewave`, а не вашу личную, и приложение их видело:
|
||
|
||
```bash
|
||
sudo chmod 2775 /srv/telewave/media/inbox /srv/telewave/media/manual
|
||
```
|
||
|
||
Забрать файл из каталога приложение сможет в любом случае: удаление зависит от прав на **каталог**
|
||
(владелец — 1654), а не на сам файл, поэтому чужой umask у ваших загрузок импорту не мешает.
|
||
|
||
**Обновление существующей установки.** Если хранилище было заведено раньше, когда контейнер работал
|
||
под root, — те же команды и есть вся миграция: выполните их на остановленном контейнере
|
||
(`docker compose down`), затем поднимайте новый образ. До смены владельца приложение стартует, но
|
||
любая запись в `/media` будет падать с `Permission denied`.
|
||
|
||
---
|
||
|
||
## 6. Проброс в контейнер (bind mount)
|
||
|
||
В `docker-compose.yml`, в сервис `app`, добавить том (этого пока **нет** в репозитории — появится
|
||
вместе с реализацией фичи, здесь для справки):
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
# ... существующая конфигурация ...
|
||
volumes:
|
||
- /srv/telewave/media:/media
|
||
mem_limit: 3g
|
||
```
|
||
|
||
И переменные окружения в `.env` (см. `docs/media-storage-and-streaming.md`):
|
||
|
||
```
|
||
Storage__RootPath=/media
|
||
```
|
||
|
||
Выбран **bind mount**: диск смонтирован в ОС через fstab (шаги 1–5) и виден всегда, независимо от
|
||
Docker — это важно, потому что файлы в `inbox/` кладутся вручную по SFTP/rsync, в том числе когда
|
||
контейнер остановлен.
|
||
|
||
> **Альтернатива — named volume, монтируемый самим Docker** (не используем, для справки). Позволяет
|
||
> пропустить шаги 3–5, но диск тогда доступен только при запущенном контейнере, а подкаталоги всё
|
||
> равно надо создавать заранее. Пример:
|
||
>
|
||
> ```yaml
|
||
> services:
|
||
> app:
|
||
> volumes:
|
||
> - media:/media
|
||
> mem_limit: 3g
|
||
> volumes:
|
||
> media:
|
||
> driver: local
|
||
> driver_opts:
|
||
> type: ext4
|
||
> device: /dev/disk/by-uuid/ВАШ-UUID
|
||
> o: noatime
|
||
> ```
|
||
>
|
||
> Разметка и `mkfs.ext4` (шаги 1–2) обязательны в любом случае.
|
||
|
||
---
|
||
|
||
## 7. Проверка записи из контейнера
|
||
|
||
После добавления тома и пересборки образа убедиться, что контейнер работает под нужным uid и пишет
|
||
на диск:
|
||
|
||
```bash
|
||
docker compose exec app id # ожидается uid=1654 gid=1654
|
||
docker compose exec app sh -c 'touch /media/.wtest && ls -l /media/.wtest && rm /media/.wtest'
|
||
```
|
||
|
||
И что вы сами можете класть файлы вручную (под своим пользователем, не через sudo):
|
||
|
||
```bash
|
||
touch /srv/telewave/media/inbox/.wtest && rm /srv/telewave/media/inbox/.wtest
|
||
```
|
||
|
||
Обе команды должны отработать без ошибок доступа. `Permission denied` в первой — не сделан
|
||
`chown -R 1654:1654` из шага 5; во второй — вы не в группе `telewave` либо не перелогинились после
|
||
`usermod`. На этом подготовка хоста завершена — дальнейшее (создание `MediaAsset`, нарезка ffmpeg)
|
||
делает уже само приложение.
|
||
|
||
---
|
||
|
||
## Приложение: если диск нужно расширить в будущем
|
||
|
||
Если VM отдаст диску больше места (например `sdb` вырастет с 700G), после увеличения на стороне
|
||
гипервизора:
|
||
|
||
```bash
|
||
sudo growpart /dev/sdb 1 # расширить раздел на весь диск
|
||
sudo resize2fs /dev/sdb1 # расширить ext4 (можно на смонтированном)
|
||
df -h /srv/telewave/media
|
||
```
|