Docs/docs/ansible/roles/navidrome.md

7.3 KiB
Raw Blame History

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

🎵 Настройка и использование

  1. Доступ к веб-интерфейсу: Откройте браузер и перейдите по адресу http://<IP_HAVI>:45136 (или через Nginx Proxy Manager, если настроен домен music.zailon.ru).
  2. Первый запуск: Создайте учетную запись администратора.
  3. Сканирование библиотеки: Перейдите в 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.