This article provides a concise technical guide for configuring an Nginx-based Least Recently Used (LRU) cache for Music Player Daemon (MPD) instances that utilize WebDAV for music storage. An advantage of this architecture is its capability to facilitate offline music playback, allowing access to cached tracks even when the WebDAV storage is inaccessible.

Furthermore, in situations where a requested track is not present in the Nginx cache and the upstream server cannot be reached, MPD is expected to automatically skip the unavailable track without removing its entry from the library database. This behavior ensures uninterrupted playback of the remaining accessible media in the queue while preserving the integrity of the music library for when the upstream becomes available again.

Prerequisites

This guide presupposes that music is stored on a WebDAV-accessible storage medium (e.g., https://music:password@nas.home.arpa/music). Furthermore, it assumes that Nginx and Music Player Daemon (MPD) are already installed on the system.

MPD configuration

The sole modification required for MPD is to direct its music_directory setting to the local Nginx proxy, as illustrated below:

music_directory		"http://127.0.0.1/music"

Nginx configuration

The following Nginx configuration excerpts highlight the pertinent directives. Irrelevant details have been omitted for brevity.

...

http {
    proxy_http_version                      1.1;
    proxy_set_header                        "Connection" "keep-alive";

    log_format with_cache_status            '$remote_addr - $upstream_cache_status [$time_local]  '
                                            '"$request" $status $body_bytes_sent '
                                            '"$http_referer" "$http_user_agent"';

    access_log                              logs/access.log with_cache_status;

    proxy_cache_path                        music_cache keys_zone=music_zone:1m max_size=5g inactive=1y levels=1:2;

    slice                                   1m;
    proxy_cache_key                         $uri$is_args$args$slice_range;
    proxy_cache_lock                        on;

    server {
        listen                              127.0.0.1:80;

        set $music_upstream_uri             "https://nas.home.arpa";

        resolver                            127.0.0.1;

        location /music {
            allow                           127.0.0.1;
            deny                            all;
            proxy_pass                      $music_upstream_uri;
            proxy_set_header                "Authorization"
                                            "Basic bXVzaWM6cGFzc3dvcmQ=";
            proxy_set_header                "Host" "nas.home.arpa";
            proxy_set_header                Range $slice_range;
            proxy_cache                     music_zone;
            proxy_cache_methods             GET;
            proxy_cache_valid               200 1s;
            proxy_cache_valid               206 1s;
            proxy_cache_revalidate          on;
            proxy_cache_use_stale           error timeout http_500 http_502 http_503 http_504;
        }
        ...
    }
    ...
}

notes for settings and their rationale include:

  • Upstream Keep-Alive: HTTP/1.1 and managed Connection: keep-alive headers reduce TCP/TLS handshake overhead with the upstream server.
  • Cache Limits: The cache is capped at 5GB (max_size=5g) with a 1-year inactivity eviction policy (inactive=1y).
  • Efficient Large File Caching: 1MB slicing enables byte-range caching of large tracks, minimizing memory footprint on buffering.
  • Download Serialization: locking prevents redundant downloads by serializing concurrent requests for the same uncached segments.
  • Dynamic Upstream Resolution: A variable for the upstream URI ($music_upstream_uri) combined with a resolver facilitates dynamic DNS resolution, adapting to server IP changes.
  • Fresh Metadata: Explicitly caching only HTTP 200/206 responses avoids caching WebDAV’s HTTP 207 Multi-Status, ensuring current directory listings.
Nginx  MPD  LRU