7.3 KiB
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
✅ Мониторинг: Логирование и проверка статуса контейнера после запуска
️Структура роли
olimp/roles/navidrome/
├── tasks/
│ └── main.yml # Основные задачи развертывания
└── templates/
── docker-compose.yml.j2 # Шаблон конфигурации Docker
️⚙️ Настройка переменных (Group Vars)
Добавьте следующие переменные в olimp/group_vars/all.yml (или в файл группы media):
# Базовые пути и настройки
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.
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) и доступен.
ansible media -m ping -i inventories/hosts
Шаг 2: Запуск роли
Используйте тег deploy_navidrome для запуска только этой роли.
cd /opt/servers/Olimp
ansible-playbook -i inventories/hosts olimp-deploy.yml -l media --tags deploy_navidrome -u root --ask-vault-pass
Ожидаемый вывод:
PLAY RECAP ******************************************************************************************************************************************************************
media : ok=11 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
✅ Если failed=0, сервер развернут успешно.
🔍 Проверка состояния Проверьте, что контейнер запущен и слушает порт:
ansible media -m shell -a "docker ps --filter name=navidrome" -u root -i inventories/hosts
Вывод должен содержать строку:
0.0.0.0:45136->4533/tcp navidrome
️🎵 Настройка и использование
- Доступ к веб-интерфейсу:
Откройте браузер и перейдите по адресу
http://<IP_HAVI>:45136(или через Nginx Proxy Manager, если настроен доменmusic.zailon.ru). - Первый запуск: Создайте учетную запись администратора.
- Сканирование библиотеки:
Перейдите в
Settings → Library → Rescan, чтобы navidrome проиндексировал музыку из/mnt/audio.
️ Работа с метаданными (Beets)
Роль автоматически устанавливает beets для ручной очистки тегов и обложек.
Вход на сервер для работы с CLI:
ssh root@media
beet import /mnt/audio/НовыйАльбом
️ Полезные команды Ansible
# Проверка синтаксиса (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.