navidrome / website

Navidrome's documentation website
https://www.navidrome.org
Apache License 2.0
18 stars 92 forks source link

Linux Install: Recommend not mounting <library_path> directly #135

Open Zuuushiiihokkiii opened 10 months ago

Zuuushiiihokkiii commented 10 months ago

Protect users from data loss if the storage backing <library_path> is unmounted and Navidrome scans the library by recommending to store <library_path> in a subdirectory of the mount point instead of mounting it directly.

Navidrome deletes all songs from the database if <library_path> exists but is an empty mount point, permanently deleting playlist contents, favourites and play counts. If <library_path> does not exist, the scan simply fails and the database is not modified.

deluan commented 8 months ago

This was already fixed in Navidrome in newer versions and should not be an issue anymore: https://github.com/navidrome/navidrome/pull/893

Are you still experiencing this?

Zuuushiiihokkiii commented 4 months ago

@deluan Hi, thanks for responding. Yes, I had some time today so I set up a test container with the latest release 51.0 to get to the bottom of this, and can confirm that this is still happening, but it's not a bug:

Why this happens

I had a look at the changes in the issue you linked: https://github.com/navidrome/navidrome/pull/893

At line 83 in tag_scanner.go I found the check to abort the scan is actually if empty && !fullScan.

This makes a lot of sense. If I remove all the content from my library and click "full scan", I would expect Navidrome to remove all the songs, and not abort the scan.

How this can quickly lead to data loss

Knowing this, this is how I lost my database:

  1. Navidrome was running, with the library mounted
  2. The connection to the storage server was lost at some point, the library was unmounted and not automatically re-mounted
  3. I uploaded some new music to the storage server
  4. I logged into Navidrome, expecting to see my new content, but it was not there... so I clicked "full scan", and since the library was not mounted, Navidrome saw an empty directory, but this was a full scan, so it did exactly what it was supposed to and deleted all songs from the database.

I had a good backup and it was no big deal, but it could be for others.

My suggestion to prevent this happening accidentally

In navidrome.service I bind the service to the mount unit with After and BindsTo. Should the library get unmounted for any reason, Navidrome will be stopped and systemd will refuse to start it until the library is successfully mounted again.

[Unit]
# Bind to mount unit, so Navidrome will never be active if the library is unmounted
After=mnt-navidrome\x2dlibrary.mount
BindsTo=mnt-navidrome\x2dlibrary.mount

This provides full protection from accidentally starting a full scan on an unmounted library.

I see no point in allowing Navidrome to start when the library is unavailable, so as far as I can tell there is no downside. Maybe something like this could be added in the installation instructions as a commented out section in the systemd unit?

deluan commented 4 months ago

I think it makes sense. Can you please open a PR to change the script? Thanks!