# 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`.