# Подготовка диска под медиахранилище (tvvm) Runbook: разметка, форматирование и монтирование диска `sdb` (700G) под хранилище TeleWave. Выполняется **один раз** на сервере `tvvm` перед запуском фичи медиа. Все команды — от root (`sudo -i` или с `sudo` перед каждой). > ⚠️ Команды разметки **уничтожают данные** на целевом диске. Диск `sdb` сейчас пустой (нет > разделов), но каждый шаг ниже содержит проверку — не пропускайте их. Итог: раздел `sdb1` (ext4) смонтирован в `/srv/telewave/media`, внутри созданы рабочие каталоги, запись из контейнера (сейчас работает под root) возможна. --- ## 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} ``` **Владелец.** Контейнер сейчас работает под `root` (в Dockerfile нет `USER`), а bind-mount пробрасывает права хоста внутрь как есть. Поэтому достаточно оставить владельцем root: ```bash sudo chown -R root:root /srv/telewave/media sudo chmod -R 755 /srv/telewave/media ``` Два каталога наполняете вы, а не приложение: - `inbox/` — разбирается сканером автоматически: файл с допустимым расширением и стабильным размером регистрируется сам и уходит в обработку; - `manual/` — **ручной разбор**: сканер сюда не заглядывает. Файлы видны в админке (Медиа → «Из папки manual»), выбираются галочками и сразу привязываются к шоу. Импортированные файлы уходят из каталога так же, как из `inbox/`. Чтобы класть в них файлы вручную (SFTP/rsync) под своим пользователем, откройте на запись именно эти каталоги вашей группе: ```bash sudo chown root:$(id -gn) /srv/telewave/media/inbox /srv/telewave/media/manual sudo chmod 775 /srv/telewave/media/inbox /srv/telewave/media/manual ``` > При переходе контейнера на non-root пользователя (если позже добавим `USER` в Dockerfile — > в aspnet-образе это обычно uid `1654`), сменить владельца на этот uid: > `sudo chown -R 1654:1654 /srv/telewave/media` (кроме `inbox` и `manual`, оставленных вам). --- ## 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. Проверка записи из контейнера После добавления тома и пересборки образа убедиться, что контейнер пишет на диск: ```bash docker compose exec app sh -c 'touch /media/.wtest && ls -l /media/.wtest && rm /media/.wtest' ``` Команда должна отработать без ошибок доступа. На этом подготовка хоста завершена — дальнейшее (создание `MediaAsset`, нарезка ffmpeg) делает уже само приложение. --- ## Приложение: если диск нужно расширить в будущем Если VM отдаст диску больше места (например `sdb` вырастет с 700G), после увеличения на стороне гипервизора: ```bash sudo growpart /dev/sdb 1 # расширить раздел на весь диск sudo resize2fs /dev/sdb1 # расширить ext4 (можно на смонтированном) df -h /srv/telewave/media ```