Deploying Navidrome with Podman on Fedora – A Step‑by‑Step Guide

By the end of this article the reader will be able to install, configure, and run the Navidrome music server on a Fedora system using Podman, with SELinux contexts correctly applied and the service managed through podman‑compose.

Understanding Navidrome and Its Container Model

Navidrome is an open‑source music‑streaming server that serves a personal audio collection over HTTP. It is distributed as a set of multi‑architecture container images that include all runtime dependencies, eliminating the need for a host‑level package manager. The images are published under the deluan/navidrome repository and support the common architectures linux/amd64, linux/arm64, linux/arm/v6, and linux/arm/v7, making the same deployment process applicable to x86 servers as well as ARM‑based devices such as Raspberry Pi.

Podman is a daemonless container engine that implements the OCI container runtime specifications. It offers Docker‑compatible command‑line syntax while providing rootless execution and tighter integration with SELinux on Fedora. Because Podman does not require a central daemon, containers can be launched directly from a user session, and the podman unshare utility can be used to perform file‑ownership changes inside the user namespace, preserving the principle of least privilege.

Preparing the Host Environment

The first step is to ensure that the host system has the required tools installed. Fedora includes Podman in its default repositories, and the optional podman-compose package provides a Docker‑Compose‑compatible front‑end.

Install the necessary packages with the following command, which adds the Podman binaries and the compose helper:

sudo dnf install -y podman podman-compose

This command installs the podman engine, the podman-compose script, and any required SELinux policy modules. The installation can be reversed by removing the packages with sudo dnf remove podman podman-compose.

Creating the Directory Structure

Navidrome expects two persistent volumes: one for its internal database and configuration (/data) and one for the music collection (/music). Create a dedicated directory hierarchy in the user’s home directory to hold these files.

mkdir -p /home/nico/navidrome/{Data,Music}

The command creates Data and Music sub‑directories under /home/nico/navidrome. Ownership and SELinux labeling will be addressed in the next steps.

Applying SELinux Contexts

When SELinux is enforcing (the default on Fedora), container processes are confined by the container_file_t type. To allow the Navidrome container to read and write its data directories, the host directories must be labeled accordingly.

Add the SELinux file context for each directory and its contents:

sudo semanage fcontext -a -t container_file_t '/home/nico/navidrome/Data(/.*)?'
sudo semanage fcontext -a -t container_file_t '/home/nico/navidrome/Music(/.*)?'

These commands register a persistent mapping that tells SELinux to treat any file under the specified paths as container_file_t. Apply the mapping immediately with:

sudo restorecon -R /home/nico/navidrome/Data
sudo restorecon -R /home/nico/navidrome/Music

If later adjustments are required, the semanage fcontext -d command can delete the rule, and restorecon can be re‑run to revert the labeling.

Setting Correct Ownership

Navidrome runs inside the container as a non‑root user with UID 1000 and GID 1000. To avoid permission errors, the host directories must be owned by the same identifiers. Because the host user may have a different UID, the podman unshare command performs the ownership change inside a user namespace, ensuring the container sees the correct ownership without requiring root privileges on the host filesystem.

podman unshare chown 1000:1000 /home/nico/navidrome/Data
podman unshare chown 1000:1000 /home/nico/navidrome/Music

These commands change the owner and group of the two directories to UID 1000/GID 1000. To revert, run the same commands with the original UID/GID values.

Defining the Container with podman‑compose

Using podman-compose simplifies multi‑container orchestration and mirrors the familiar Docker‑Compose workflow. Create a podman-compose.yml file in the same directory as the data volumes.

cat > podman-compose.yml <<'EOF'
version: "3"
services:
  navidrome:
    image: deluan/navidrome:latest
    user: 1000:1000
    ports:
      - "4533:4533"
    restart: unless-stopped
    environment:
      ND_SCANSCHEDULE: 1h
      ND_LOGLEVEL: info
      ND_SESSIONTIMEOUT: 24h
      ND_BASEURL: ""
    volumes:
      - "/home/nico/navidrome/Data:/data"
      - "/home/nico/navidrome/Music:/music:ro"
EOF

The file declares a single service named navidrome. Key elements:

  • image: pulls the latest official Navidrome image from Docker Hub.
  • user: runs the container with UID/GID 1000, matching the host directory ownership.
  • ports: maps host port 4533 to the container’s HTTP port.
  • restart: ensures the container restarts automatically unless stopped manually.
  • environment: optional variables that control scan frequency, log level, session timeout, and base URL. The values shown are the defaults; they can be omitted or customized as needed.
  • volumes: mounts the persistent data directory as read/write (/data) and the music collection as read‑only (/music:ro) to prevent accidental modification from within the container.

Launching the Service

Start the Navidrome container in detached mode with:

podman-compose up -d

Podman pulls the image if it is not already cached, creates the container, and starts it. The -d flag runs the container in the background. To stop and remove the service, use:

podman-compose down

The command stops the container and removes the associated pod and network resources, leaving the host‑side data directories untouched.

Alternative One‑Shot Run Command

For environments where a compose file is unnecessary, the same container can be launched directly with a single podman run invocation. This approach is useful for quick tests or when integrating Navidrome into an existing script.

podman run -d \
  --name navidrome \
  --restart=unless-stopped \
  --user $(id -u):$(id -g) \
  -v /home/nico/navidrome/Music:/music:ro \
  -v /home/nico/navidrome/Data:/data \
  -p 4533:4533 \
  -e ND_LOGLEVEL=info \
  deluan/navidrome:latest

Explanation of the flags:

  • -d: run in detached mode.
  • --name: assign a stable container name for later management.
  • --restart=unless-stopped: replicate the compose restart policy.
  • --user $(id -u):$(id -g): dynamically set the UID/GID to match the invoking user, ensuring correct file permissions.
  • -v: bind‑mount the host directories; the music mount is read‑only.
  • -p: expose port 4533 on the host.
  • -e: set environment variables; only ND_LOGLEVEL is shown as an example.

To stop this container, execute podman stop navidrome followed by podman rm navidrome. The data stored in the host directories remains intact.

Verification and Routine Operations

After the container is running, verify that Navidrome is reachable by requesting the HTTP endpoint:

curl -s http://localhost:4533/ | grep -i navidrome

A successful response contains the Navidrome HTML title, confirming that the service is listening on the expected port. For a more detailed health check, inspect the container logs:

podman logs navidrome

Typical log entries include the startup banner, the configured scan schedule, and any errors related to accessing the music directory. Because the music mount is read‑only, permission‑denied messages indicate an SELinux labeling issue; re‑run restorecon if necessary.

To trigger a manual library rescan without restarting the container, set the ND_SCANSCHEDULE environment variable to 0 and send a SIGHUP to the process. This can be done via podman exec:

podman exec navidrome pkill -HUP navidrome

The command sends a hang‑up signal to the Navidrome process, causing it to re‑read the music directory. The operation does not modify container configuration and can be reversed by sending a regular SIGTERM to stop the container if needed.

Trade‑offs and Operational Considerations

Deploying Navidrome with Podman on Fedora offers several advantages:

  • Rootless operation: By running containers as an unprivileged user, the attack surface is reduced compared with traditional Docker daemons.
  • SELinux integration: Proper labeling ensures that the container cannot escape its confined file‑system view, complying with Fedora’s default security posture.
  • Architecture portability: The same compose file works on both x86_64 and ARM platforms, simplifying management of heterogeneous hardware.

However, there are practical trade‑offs to consider:

  • Performance of bind mounts: Accessing a large music library over a bind mount may incur additional overhead compared with using a dedicated volume driver. Monitoring I/O latency on the host can reveal bottlenecks.
  • Backup strategy: The /data directory contains the Navidrome SQLite database and configuration files. Regular backups of /home/nico/navidrome/Data are required to protect against data loss, as container restarts do not affect the host‑side files.
  • Network exposure: Exposing port 4533 directly to the host makes the service reachable on any network interface. In production environments, consider placing a reverse proxy (e.g., Nginx) in front of Navidrome to enforce TLS and add authentication layers.
  • Resource limits: Podman does not impose default CPU or memory limits. For high‑traffic deployments, define explicit --cpus and --memory constraints in the compose file to prevent a single container from exhausting host resources.

By following the steps outlined above, system administrators can maintain a reproducible, SELinux‑compliant Navidrome deployment that remains functional across hardware revisions and Fedora updates for the foreseeable future.

Source: fedoramagazine.org

Comments

Popular Posts

Install Ollama and Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install a Local AI Chatbot on Ubuntu 24.04 with Ollama and Open WebUI (Step-by-Step)

Install Ollama + Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Trending Now

Homogeneous Nucleation on Mars: A Textbook Process Finally Observed in Nature

By the end of this piece, you will understand what the Arsia Mons Elongated Cloud is, why it resisted explanation for several years after its first observation, and what the newly published model reveals about a physical process that has never been directly confirmed on any planet's atmosphere. The cloud that broke the model Every morning during Martian spring and summer, a thin, extremely long cloud forms near the Arsia Mons volcano and gradually elongates until it stretches to more than 1,000 miles before dissipating. The cycle then repeats for several months. The formation was first recorded by a probe in 2018, and from that point onward it became a persistent puzzle for atmospheric scientists working with Mars data. The cloud's geometry, its timing, and its seasonal recurrence all pointed to a real and reproducible physical process, yet no existing model could reproduce it. For a technical audience familiar with simulation work, the situation is analogous to a product...