Set up Fugue (merge multiple servers)

Fugue is for people who already have more than one Navidrome server — say, one at home and one at the cabin, or one of your own and one shared with a friend. Fugue stitches them together so they look like a single library.

≈ 20 minutes A bit techy Docker Optional
Do I need Fugue? What's this?

Probably not, if you only have one server. Fugue is the answer to: "I have music on two different machines — can I see them as one library, with no duplicates?" If that's not your problem, skip this tutorial.

  1. Get Fugue

    Fugue is distributed as a Docker image — no prebuilt standalone binaries. Pull the latest from GitHub Container Registry:

    docker pull ghcr.io/andvision/fugue:latest

    Image page: ghcr.io/andvision/fugue. Source: github.com/andvision/fugue.

    No Docker? Build from source

    Fugue is Rust. With rustup installed, clone and build a release binary:

    git clone https://github.com/andvision/fugue
    cd fugue
    cargo build --release
    ./target/release/fugue serve

    First build takes a few minutes — pulls every dependency. The resulting binary is self-contained.

  2. Make a settings file

    In a folder you'll remember (e.g. ~/fugue), create fugue.toml with your servers:

    # fugue.toml — basic two-server setup
    
    [server]
    listen = "0.0.0.0:4040"
    
    [[backends]]
    name     = "home"
    url      = "http://192.168.1.42:4533"
    username = "anna"
    password = "your-navidrome-password"
    
    [[backends]]
    name     = "cabin"
    url      = "https://music.cabin.example.com"
    username = "anna"
    password = "another-password"
    What's a "backend"?

    In Fugue's settings, each Navidrome server you want to merge is called a "backend." You can have two, three, ten — Fugue talks to all of them in parallel and combines the results.

    Is it safe to put my password in this file?

    The file lives only on your machine, in a folder only you can read. If you want extra safety, set the file's permissions so only your user can open it:

    chmod 600 fugue.toml

    You can also use environment variables instead — see the FUGUE_ overrides in the docs.

  3. Start Fugue

    From the folder containing fugue.toml:

    docker run -d --name fugue \
      --restart unless-stopped \
      -p 4040:4040 \
      -v "$(pwd)/fugue.toml:/etc/fugue/fugue.toml:ro" \
      ghcr.io/andvision/fugue:latest serve

    Watch logs with docker logs -f fugue. Fugue probes every backend on startup and reports any that are unreachable.

    Prefer docker compose?

    Drop a compose.yaml next to fugue.toml:

    services:
      fugue:
        image: ghcr.io/andvision/fugue:latest
        container_name: fugue
        restart: unless-stopped
        ports:
          - "4040:4040"
        volumes:
          - ./fugue.toml:/etc/fugue/fugue.toml:ro
        command: serve

    Then docker compose up -d.

    Built from source instead?

    Just run the binary:

    ./target/release/fugue serve

    It reads fugue.toml from the working directory.

  4. Check it works

    Open in a browser:

    http://localhost:4040/rest/ping?u=anna&p=YOUR_FUGUE_PASSWORD&v=1.16.1&c=test&f=json

    You should see {"subsonic-response":{"status":"ok",...}}. That confirms Fugue is up and speaking the Subsonic API. Now any Subsonic-compatible app — including Moosic — can connect to Fugue and see all your servers as one library.

  5. (Optional) Auto-start on boot

    Docker: the --restart unless-stopped flag above already handles this — Fugue comes back after every reboot.

    From-source binary: wrap it in a systemd unit at /etc/systemd/system/fugue.service:

    [Unit]
    Description=Fugue Subsonic proxy
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=fugue
    WorkingDirectory=/opt/fugue
    ExecStart=/opt/fugue/fugue serve
    Restart=on-failure
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target

    Adjust User and paths to where the binary and fugue.toml actually live. Then:

    sudo systemctl daemon-reload
    sudo systemctl enable --now fugue
    sudo systemctl status fugue
← all tutorials