Lidarr next to an existing media pod
Lidarr as a standalone quadlet that joins an existing media stack without touching the pod.
- Standalone container
- Rootless: systemctl --user
- Tested with podman 5.0 and newer
Last updated
See where this fits on the homelab connections map, with every port it uses.
In short: Adding a port to a running podman pod means recreating the pod and restarting every app in it. A new *arr app such as Lidarr can run as its own container instead: it publishes port 8686 itself, mounts the same /srv/media folder as /data, and reaches Prowlarr and NZBGet at host.containers.internal. On a fresh install, you can put it in the pod instead, as the media stack example shows.
The quadlet files
Every quadlet file below passes podman's quadlet generator and
systemd-analyze verify on podman 5.0 and the current release. Personal values
are placeholders: replace example.com, /srv/... paths and the
time zone with your own.
lidarr.container
Save as ~/.config/containers/systemd/lidarr.container
[Unit]
Description=Lidarr music manager
StartLimitIntervalSec=0
After=network-online.target
[Container]
Image=lscr.io/linuxserver/lidarr:latest
ContainerName=lidarr
AutoUpdate=registry
Environment=TZ=Etc/UTC
# Standalone next to an existing media pod: adding a port to a running pod means
# recreating the pod. Lidarr reaches Prowlarr and NZBGet via host.containers.internal.
PublishPort=8686:8686
Volume=lidarr.volume:/config
# The same /data layout as the media pod, so download paths match and imports are
# instant moves or hardlinks.
Volume=/srv/media:/data
HealthCmd=curl -fsS -o /dev/null http://127.0.0.1:8686/ping
HealthInterval=1m
HealthTimeout=10s
HealthRetries=3
HealthStartPeriod=3m
HealthOnFailure=kill
[Service]
Restart=always
RestartSec=30
TimeoutStartSec=900
[Install]
WantedBy=default.target
lidarr.volume
Save as ~/.config/containers/systemd/lidarr.volume
[Unit]
Description=Lidarr config and database
[Volume]
VolumeName=lidarr
Caddyfile
Save as /etc/caddy/Caddyfile
lidarr.example.com {
reverse_proxy 10.0.0.10:8686
}
Why is it built this way?
What it is. Lidarr does for music what Radarr does for films: it follows artists, finds releases through Prowlarr, sends them to NZBGet and files the result into your library.
Pod or standalone. The media stack
pod shares one network namespace, so its apps talk over localhost. That is tidy
until you add an app to a running stack: pod ports are fixed when the pod is created. This
quadlet keeps Lidarr outside and uses host.containers.internal to reach the pod's
published ports instead. Both shapes work; pick the one that fits your stack.
Same folders, same paths. Lidarr mounts /srv/media as
/data, exactly like the apps in the pod. NZBGet reports a finished download as
/data/downloads/..., and Lidarr finds it at that path and moves it within one
filesystem, without copying.
Caddy in front of Lidarr
The *arr apps need nothing special behind Caddy. Keep their own login on (Settings, General, Authentication) because the page can start downloads. The Caddyfile generator writes the site block.
Check that it works
systemctl --user status lidarr.service
curl -s http://127.0.0.1:8686/ping; echo
# can Lidarr reach Prowlarr in the pod?
podman exec lidarr curl -fsS -o /dev/null -w '%{http_code}\n' http://host.containers.internal:9696/ping
See quadlet basics for how the generated
lidarr.service works.
How do I start it?
Run these as your normal user, not as root. Quadlet reads ~/.config/containers/systemd/ for user services.
mkdir -p ~/.config/containers/systemd /srv/media/music
podman unshare chown 911:911 /srv/media/music
systemctl --user daemon-reload
systemctl --user start lidarr.service
# open http://<server>:8686: root folder /data/music
# download client NZBGet: host host.containers.internal, port 6789
# in Prowlarr: add Lidarr at http://host.containers.internal:8686 with Lidarr's API key
Check the result with systemctl --user status and
the logs with journalctl --user -u followed by the
service name. To turn a docker-compose file of your own into files like these, use the
compose to quadlet converter.
Common mistakes
Lidarr cannot import: the download path does not exist
Lidarr must see finished downloads at the same path as NZBGet. Both mount /srv/media as /data here, so /data/downloads is the same folder in both. Do not add a separate /downloads mount.
Prowlarr cannot reach Lidarr at localhost:8686
Prowlarr runs in the media pod, where localhost means the pod. Lidarr is outside it, so use http://host.containers.internal:8686 in Prowlarr, and host.containers.internal:9696 for Prowlarr in Lidarr.
PublishPort= is refused when I add Lidarr to the pod
A container inside a pod cannot publish ports; the pod does. Add PublishPort=8686:8686 to media.pod and recreate the pod with systemctl --user restart media-pod.service, or run Lidarr standalone as shown here.
Frequently asked questions
Why not add Lidarr to the media pod?
You can, and on a new install that is the neater shape. On a running stack, a new port on the pod means recreating it, which restarts every download and import in progress. A standalone container joins without touching the others.
Does the same approach work for Readarr or other *arr apps?
Yes. Copy the quadlet, change the image, container name, port, volume name and health check path, and keep the shared /srv/media:/data mount so imports stay instant.