Document Atlas backend phase one and WireGuard deployment

This commit is contained in:
Fabio Scotto di Santolo
2026-09-12 17:19:20 +02:00
parent 64aebe8c34
commit 8c35ef63c9
35 changed files with 780 additions and 554 deletions

View File

@@ -9,29 +9,3 @@
tags: [services]
ansible.builtin.systemd:
daemon_reload: true
- name: Restart rclone music mount
tags: [services, rclone, navidrome]
ansible.builtin.systemd:
name: "{{ server_rclone_music_service }}"
state: restarted
daemon_reload: true
when:
- server_atlas_music_enabled | bool
- not ansible_check_mode
- name: Restart rootless Navidrome
tags: [services, podman, rclone, navidrome]
become_user: "{{ server_username }}"
ansible.builtin.systemd:
name: navidrome.service
scope: user
state: restarted
daemon_reload: true
environment:
XDG_RUNTIME_DIR: "/run/user/{{ ansible_facts['getent_passwd'][server_username][1] }}"
DBUS_SESSION_BUS_ADDRESS: >-
unix:path=/run/user/{{ ansible_facts['getent_passwd'][server_username][1] }}/bus
when:
- server_atlas_music_enabled | bool
- not ansible_check_mode

View File

@@ -8,17 +8,6 @@
fail_msg: >-
server_firewall_backend must be firewalld for the Rocky server profile.
- name: Require server database secret variables
tags: [dotfiles, dotfiles:server, services, navidrome]
ansible.builtin.assert:
that:
- server_navidrome_db_password | length > 0
- (vault_postgres_root_password | default('')) | length > 0
fail_msg: >-
Define vault_navidrome_db_password and vault_postgres_root_password in Vault
before rendering the Navidrome database configuration.
no_log: true
- name: Configure DuckDNS updater
tags: [dotfiles, dotfiles:server, duckdns]
ansible.builtin.import_tasks: duckdns.yml
@@ -72,12 +61,6 @@
tags: [services, podman]
ansible.builtin.include_tasks: podman-compose.yml
- name: Configure Atlas music mount
ansible.builtin.import_tasks: rclone-music.yml
- name: Configure rootless Navidrome
ansible.builtin.import_tasks: navidrome.yml
- name: Disable SSH root login on server
tags: [services]
ansible.builtin.lineinfile:

View File

@@ -1,114 +0,0 @@
---
- name: Read server account details for rootless Navidrome
tags: [services, podman, rclone, navidrome]
ansible.builtin.getent:
database: passwd
key: "{{ server_username }}"
when: server_atlas_music_enabled | bool
- name: Check for a running legacy rootful Navidrome container
tags: [services, podman, navidrome]
ansible.builtin.command:
argv:
- podman
- container
- inspect
- --format
- "{{ '{{.State.Running}}' }}"
- navidrome
register: server_legacy_navidrome_container
changed_when: false
failed_when: false
check_mode: false
when: server_atlas_music_enabled | bool
- name: Refuse concurrent legacy and rootless Navidrome
tags: [services, podman, navidrome]
ansible.builtin.assert:
that:
- >-
server_legacy_navidrome_container.rc != 0
or server_legacy_navidrome_container.stdout | trim != 'true'
fail_msg: >-
Stop the legacy rootful Navidrome container before enabling the rootless Quadlet.
The playbook does not remove the old container or its data automatically.
when: server_atlas_music_enabled | bool
- name: Enable lingering for rootless Navidrome
tags: [services, podman, navidrome]
ansible.builtin.command:
argv:
- loginctl
- enable-linger
- "{{ server_username }}"
creates: "/var/lib/systemd/linger/{{ server_username }}"
when: server_atlas_music_enabled | bool
- name: Start server user systemd manager
tags: [services, podman, navidrome]
ansible.builtin.systemd:
name: "user@{{ ansible_facts['getent_passwd'][server_username][1] }}.service"
state: started
when:
- server_atlas_music_enabled | bool
- not ansible_check_mode
- name: Create rootless Navidrome Quadlet directory
tags: [services, podman, navidrome]
ansible.builtin.file:
path: "{{ server_navidrome_quadlet_dir }}"
state: directory
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0700"
when: server_atlas_music_enabled | bool
- name: Create private rootless Navidrome configuration directory
tags: [services, podman, navidrome]
ansible.builtin.file:
path: "{{ server_navidrome_env_dir }}"
state: directory
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0700"
when: server_atlas_music_enabled | bool
- name: Render Vault-backed rootless Navidrome environment
tags: [services, podman, navidrome]
ansible.builtin.template:
src: navidrome.env.j2
dest: "{{ server_navidrome_env_file }}"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0600"
no_log: true
diff: false
notify: Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Render rootless Navidrome Quadlet
tags: [services, podman, navidrome]
ansible.builtin.template:
src: navidrome.container.j2
dest: "{{ server_navidrome_quadlet_dir }}/navidrome.container"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0644"
notify: Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Start rootless Navidrome Quadlet
tags: [services, podman, navidrome]
become_user: "{{ server_username }}"
ansible.builtin.systemd:
name: navidrome.service
scope: user
state: started
daemon_reload: true
environment:
XDG_RUNTIME_DIR: "/run/user/{{ ansible_facts['getent_passwd'][server_username][1] }}"
DBUS_SESSION_BUS_ADDRESS: >-
unix:path=/run/user/{{ ansible_facts['getent_passwd'][server_username][1] }}/bus
when:
- server_atlas_music_enabled | bool
- not ansible_check_mode

View File

@@ -1,105 +0,0 @@
---
- name: Require completed Atlas SFTP mount configuration
tags: [services, rclone, navidrome]
ansible.builtin.assert:
that:
- server_atlas_sftp_host != 'CHANGEME_ATLAS_WIREGUARD_IP'
- server_atlas_sftp_known_host != 'CHANGEME_ATLAS_SSH_HOST_KEY'
- server_atlas_sftp_known_host | length > 0
- server_atlas_sftp_private_key | length > 0
- server_atlas_sftp_remote_path == '/pool/media/music'
fail_msg: >-
Define the Atlas WireGuard address, pinned SSH host key and Vault-backed
SFTP private key before enabling the music mount.
no_log: true
when: server_atlas_music_enabled | bool
- name: Create private rclone configuration directory
tags: [services, rclone, navidrome]
ansible.builtin.file:
path: "{{ server_rclone_config_dir }}"
state: directory
owner: root
group: "{{ server_user_group }}"
mode: "0750"
when: server_atlas_music_enabled | bool
- name: Install Vault-backed Atlas SFTP private key
tags: [services, rclone, navidrome]
ansible.builtin.copy:
content: "{{ server_atlas_sftp_private_key | trim }}\n"
dest: "{{ server_atlas_sftp_private_key_file }}"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0600"
no_log: true
diff: false
notify:
- Restart rclone music mount
- Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Install pinned Atlas SSH host key
tags: [services, rclone, navidrome]
ansible.builtin.copy:
content: "{{ server_atlas_sftp_known_host | trim }}\n"
dest: "{{ server_atlas_sftp_known_hosts_file }}"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0640"
notify:
- Restart rclone music mount
- Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Render Atlas SFTP rclone configuration
tags: [services, rclone, navidrome]
ansible.builtin.template:
src: rclone.conf.j2
dest: "{{ server_rclone_config_file }}"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0600"
notify:
- Restart rclone music mount
- Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Create rclone music directories
tags: [services, rclone, navidrome]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0750"
loop:
- "{{ server_rclone_music_mountpoint }}"
- "{{ server_rclone_music_cache_dir }}"
loop_control:
label: "{{ item }}"
when: server_atlas_music_enabled | bool
- name: Render rclone music system service
tags: [services, rclone, navidrome]
ansible.builtin.template:
src: rclone-music.service.j2
dest: "/etc/systemd/system/{{ server_rclone_music_service }}"
owner: root
group: root
mode: "0644"
notify:
- Restart rclone music mount
- Restart rootless Navidrome
when: server_atlas_music_enabled | bool
- name: Enable and start rclone music mount
tags: [services, rclone, navidrome]
ansible.builtin.systemd:
name: "{{ server_rclone_music_service }}"
enabled: true
state: started
daemon_reload: true
when:
- server_atlas_music_enabled | bool
- not ansible_check_mode

View File

@@ -1,21 +0,0 @@
# Managed by Ansible. Do not edit manually.
[Unit]
Description=Rootless Navidrome music server
[Container]
ContainerName=navidrome
Image={{ server_navidrome_image }}
Network=host
EnvironmentFile={{ server_navidrome_env_file }}
Volume={{ server_navidrome_data_dir }}:/data
Volume={{ server_rclone_music_mountpoint }}:/music:ro
SecurityLabelDisable=true
[Service]
ExecStartPre=/usr/bin/mountpoint -q {{ server_rclone_music_mountpoint }}
Restart=always
RestartSec=10s
TimeoutStartSec=900
[Install]
WantedBy=default.target

View File

@@ -1,7 +0,0 @@
# Managed by Ansible. Contains a Vault secret; do not edit or copy.
ND_DATABASE_URL={{ ('postgres://navidrome:' ~ server_navidrome_db_password ~ '@127.0.0.1:5432/navidrome_db?sslmode=disable') | to_json }}
ND_PORT={{ server_navidrome_port }}
ND_SCANSCHEDULE="1h"
ND_SESSIONTIMEOUT="24h"
ND_ENABLETRANSCODING="true"
ND_LOGLEVEL="info"

View File

@@ -1,29 +0,0 @@
[Unit]
Description=Read-only Atlas music mount via rclone SFTP
Wants=network-online.target
After=network-online.target
{% if server_atlas_wireguard_unit | length > 0 %}
Wants={{ server_atlas_wireguard_unit }}
After={{ server_atlas_wireguard_unit }}
{% endif %}
[Service]
Type=notify
User={{ server_username }}
Group={{ server_user_group }}
ExecStart=/usr/bin/rclone mount \
{{ server_atlas_sftp_remote_name }}:{{ server_atlas_sftp_remote_path }} \
{{ server_rclone_music_mountpoint }} \
--config {{ server_rclone_config_file }} \
--cache-dir {{ server_rclone_music_cache_dir }} \
--read-only \
--vfs-cache-mode full \
--vfs-cache-max-size 15G \
--vfs-read-chunk-size 5M \
--dir-cache-time 24h
ExecStop=-/usr/bin/fusermount3 -uz {{ server_rclone_music_mountpoint }}
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

View File

@@ -1,9 +0,0 @@
# Managed by Ansible. Authentication uses the separately deployed Vault-backed key.
[{{ server_atlas_sftp_remote_name }}]
type = sftp
host = {{ server_atlas_sftp_host }}
user = {{ server_atlas_sftp_username }}
port = {{ server_atlas_sftp_port }}
key_file = {{ server_atlas_sftp_private_key_file }}
known_hosts_file = {{ server_atlas_sftp_known_hosts_file }}
shell_type = unix