diff --git a/docs/ansible/roles/navidrome.md b/docs/ansible/roles/navidrome.md new file mode 100644 index 0000000..7f39cf7 --- /dev/null +++ b/docs/ansible/roles/navidrome.md @@ -0,0 +1,140 @@ +# Navidrome Music Server — Ansible Role Deployment +| Роль | Целевой хост | Путь | Порт | Тип | +|----------|---------|---------|---------|---------| +|`navidrome`|`media` (LXC)|`/mnt/service/navidrome`|`4533` (внутренний), `45136` (внешний)|Self-hosted Subsonic-сервер| + + +## 📋 Описание +Ansible-роль для полного цикла развертывания музыкального сервера navidrome. Обеспечивает автоматическую установку зависимостей (`beets` для метаданных), настройку структуры директорий, генерацию конфигураций Docker и запуск контейнеров без необходимости ручного входа в систему. + +### Особенности: +✅ **Идемпотентность:** Повторный запуск не ломает существующее состояние +✅ **Автоматизация:** Установка пакетов, прав доступа и Docker-композиции в одном шаге +✅ **Интеграция с Vault:** Поддержка секретов через `ansible-vault` +✅ **Мониторинг:** Логирование и проверка статуса контейнера после запуска + +## ️Структура роли +```text +olimp/roles/navidrome/ +├── tasks/ +│ └── main.yml # Основные задачи развертывания +└── templates/ + ── docker-compose.yml.j2 # Шаблон конфигурации Docker +``` + +## ️⚙️ Настройка переменных (Group Vars) +Добавьте следующие переменные в `olimp/group_vars/all.yml` (или в файл группы `media`): + +```yaml +# Базовые пути и настройки +navidrome_base_dir: "{{ service_config_base }}/navidrome" +navidrome_data_dir: "{{ navidrome_base_dir }}/data" +navidrome_plugins_dir: "{{ navidrome_base_dir }}/plugins" +navidrome_port: "45136" +navidrome_default_language: "ru" +navidrome_music_folder: "/mnt/audio" +navidrome_log_level: "info" + +# Установка зависимостей для метаданных +navidrome_install_beets: true +``` + +## ️⚙️ Шаблоны конфигурации +Файл `templates/docker-compose.yml.j2` генерирует `docker-compose.yml` на основе переменных Ansible. + +```yaml +services: + navidrome: + image: deluan/navidrome:latest + container_name: navidrome + user: "1000:1000" + ports: + - "{{ navidrome_port }}:4533" + volumes: + - "{{ navidrome_data_dir }}:/data" + - "{{ navidrome_music_folder }}:/music:ro" + environment: + - TZ={{ timezone }} + - ND_MUSICFOLDER=/music + - ND_DATAFOLDER=/data + - ND_PORT=4533 + - ND_LOGLEVEL={{ navidrome_log_level }} + - ND_DEFAULTLANGUAGE={{ navidrome_default_language }} + restart: unless-stopped + security_opt: + - no-new-privileges:true +``` + +## ️🚀 Развертывание через Ansible +### ️Шаг 1: Подготовка +Убедитесь, что хост `media` прописан в инвентаре (`inventories/hosts`) и доступен. + +```bash +ansible media -m ping -i inventories/hosts +``` + +### Шаг 2: Запуск роли +Используйте тег `deploy_navidrome` для запуска только этой роли. +```bash +cd /opt/servers/Olimp +ansible-playbook -i inventories/hosts olimp-deploy.yml -l media --tags deploy_navidrome -u root --ask-vault-pass +``` +```text +Ожидаемый вывод: +PLAY RECAP ****************************************************************************************************************************************************************** +media : ok=11 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +✅ Если `failed=0`, сервер развернут успешно. + +🔍 Проверка состояния +Проверьте, что контейнер запущен и слушает порт: + +```bash +ansible media -m shell -a "docker ps --filter name=navidrome" -u root -i inventories/hosts +``` + +Вывод должен содержать строку: +`0.0.0.0:45136->4533/tcp navidrome` + +## ️🎵 Настройка и использование +1. Доступ к веб-интерфейсу: + Откройте браузер и перейдите по адресу `http://:45136` (или через Nginx Proxy Manager, если настроен домен `music.zailon.ru`). +2. Первый запуск: + Создайте учетную запись администратора. +3. Сканирование библиотеки: + Перейдите в `Settings → Library → Rescan`, чтобы navidrome проиндексировал музыку из `/mnt/audio`. + +## ️ Работа с метаданными (Beets) +Роль автоматически устанавливает `beets` для ручной очистки тегов и обложек. +Вход на сервер для работы с CLI: + +```bash +ssh root@media +beet import /mnt/audio/НовыйАльбом +``` + +## ️ Полезные команды Ansible +```bash +# Проверка синтаксиса (Dry Run) +ansible-playbook -i inventories/hosts olimp-deploy.yml -l media --tags deploy_navidrome --check + +# Запуск с подробным выводом (Debug) +ansible-playbook -i inventories/hosts olimp-deploy.yml -l media --tags deploy_navidrome -vvv + +# Перезапуск сервиса через Ansible (Ad-hoc) +ansible media -m docker_compose -a "project_src=/mnt/service/navidrome state=restarted" -u root +``` + +## ️🚨 Решение проблем +| Проблема | Причина | Решение | +|----------|---------|---------| +| `failed: [media] ... template error` | Ошибка в Jinja-шаблоне (например, `{% endif %}` без `{% if %}`) | Проверьте файл `templates/docker-compose.yml.j2` на синтаксис YAML и Jinja2. | +| Контейнер не запускается | Ошибка прав доступа к томам | Убедитесь, что `navidrome_data_dir` принадлежит пользователю `1000:1000`. Задача `Set correct ownership` должна пройти успешно. | +| `port is already allocated` | Конфликт портов на хосте | Измените переменную `navidrome_port` в `group_vars`. | +| Музыка не видна | Неверный путь монтирования | Проверьте `navidrome_music_folder` и убедитесь, что папка `/mnt/audio` существует на хосте `media`. | + +🔐 Безопасность +- **User Namespace:** Контейнер запускается от `user: "1000:1000"`, что снижает риски при компрометации сервиса. +- **Read-Only Music:** Музыкальная библиотека монтируется в режиме `ro` (только чтение), предотвращая случайное удаление файлов сервером. +- **Vault:** Все чувствительные данные (если добавляются в будущем) должны храниться в `vault.yml`. \ No newline at end of file