Lidarr on PMSS
Lidarr follows the artists you choose and keeps your music library organised. On a Pulsed Media seedbox it runs in rootless Docker at your own address, behind its own login; it used about 385 MiB of memory a minute after start with an empty library. The steps below create that login and switch analytics off before any port opens. Tested on a Pulsed Media seedbox on 24 October 2026 with lscr.io/linuxserver/lidarr 3.1.0.4875-ls45.

PMSS keeps a Lidarr build in /opt/Lidarr on each server (Pulsed Media Seedbox and Storage Features), but as of October 2026 Install Media Stack does not set Lidarr up in your account. This guide runs the LinuxServer.io container instead, which keeps Lidarr's files under ~/docker/lidarr and its version pinned until you change it. Running the /opt build was not part of the test.
Privacy
Level: MEDIUM. Using Lidarr reduces your privacy. What it sends out of your account, from Lidarr's source code on GitHub (read on the develop branch, not at the tested release tag):
- Every artist and album you search for or add is looked up on the Lidarr project's metadata server,
api.lidarr.audio(LidarrCloudRequestBuilder.cs). That server sees what your library holds. Turning analytics off does not change this. - With default settings Lidarr sends error reports to the Servarr project's Sentry server and marks its update check as an active install (
ReconfigureLogging.cs,UpdatePackageProvider.cs). Step 1 setsLIDARR__LOG__ANALYTICSENABLED=False; per the source that turns both off. In the test the setting read back asanalyticsEnabled: false; network traffic was not captured. - The update check itself still runs. Lidarr does not update itself in this image; you update by pulling a newer image.
- An indexer or download client you add receives what you search for and fetch with it.
Requirements
| Need | Lidarr on PMSS |
|---|---|
| Memory | 385 MiB about one minute after start with an empty library, measured on a test account with a 4000 MiB memory limit. Check your own limit and use with userShowLimits (UserShowLimits on PMSS).
|
| Disk and file quota | The image counts toward your disk and file quota. The test measured the Lidarr and Bazarr images together, not separately: 24,763 files and 910 MB for the whole test account. Check yours with quota -s.
|
| Own login | Yes. Created in step 2, while no port is published. |
| Address | https://SERVER/user-USERNAME/lidarr/ through your own web server. Lidarr's URL base setting carries the path, so the proxy fragment needs no map-urlpath.
|
| Other apps | An indexer and a download client to fetch anything; connecting them was not part of the test. |
Install
Replace USERNAME with your account name, SERVER with your server's name as it appears in your panel address, and PORT with a free port between 2000 and 38000 that ss -tln does not list. Other accounts on the same server can connect to 127.0.0.1, so Lidarr starts once with no port published, gets its login from inside the container, and only then gets its port. Lidarr has no environment or config-file setting that creates the first user; its API does.
1. Make the folders, a random password and the settings file. Run this step once: running it again replaces the password and the API key, and the login made in step 2 would no longer match login.pw. The password and the API key stay in files only you can read. mkdir -p leaves folders that already exist as they are.
cd ~ mkdir -p ~/docker/lidarr/config ~/music ~/downloads chmod 700 ~/docker/lidarr umask 077 openssl rand -base64 24 | tr -d '\n' > ~/docker/lidarr/login.pw cat > ~/docker/lidarr/lidarr.env <<EOF PUID=0 PGID=0 TZ=Etc/UTC LIDARR__SERVER__URLBASE=/user-USERNAME/lidarr LIDARR__AUTH__METHOD=Forms LIDARR__AUTH__REQUIRED=Enabled LIDARR__LOG__ANALYTICSENABLED=False LIDARR__AUTH__APIKEY=$(openssl rand -hex 16) EOF chmod 600 ~/docker/lidarr/lidarr.env ~/docker/lidarr/login.pw
PUID=0 and PGID=0 make the files Lidarr writes belong to your own account.
2. Start it with no port published, then create the login from inside the container. The image is pinned to the digest that was tested.
docker run -d --name lidarr --env-file ~/docker/lidarr/lidarr.env \ -v ~/docker/lidarr/config:/config -v ~/music:/music -v ~/downloads:/downloads \ lscr.io/linuxserver/lidarr@sha256:d8549ff9ea29b4015c32257360652c1000c31ea471a2b3f0835ae77292faf35b docker exec lidarr curl -s http://127.0.0.1:8686/user-USERNAME/lidarr/ping
Repeat the last command until it prints {"status":"OK"}; in the test that took under 40 seconds. Then create the user admin with the password from login.pw. The password goes into a temporary settings file that Docker passes to the container, so you never type it on a command line and it stays out of your shell history:
{ cat ~/docker/lidarr/lidarr.env; printf 'LOGIN_USER=admin\nLOGIN_PW=%s\n' "$(cat ~/docker/lidarr/login.pw)"; } > ~/docker/lidarr/setup.env
chmod 600 ~/docker/lidarr/setup.env
docker exec --env-file ~/docker/lidarr/setup.env lidarr sh -c '
B=http://127.0.0.1:8686/user-USERNAME/lidarr/api/v1/config/host
H="X-Api-Key: $LIDARR__AUTH__APIKEY"
curl -s -H "$H" $B > /tmp/host.json
sed -i -e "s|\"username\": \"\"|\"username\": \"$LOGIN_USER\"|" \
-e "s|\"password\": *\"[^\"]*\"|\"password\": \"$LOGIN_PW\"|" \
-e "s|\"passwordConfirmation\": *\"[^\"]*\"|\"passwordConfirmation\": \"$LOGIN_PW\"|" /tmp/host.json
curl -s -o /dev/null -w "PUT %{http_code}\n" -X PUT -H "$H" -H "Content-Type: application/json" --data-binary @/tmp/host.json $B/1
rm -f /tmp/host.json'
rm -f ~/docker/lidarr/setup.env
Expect PUT 202, the code for an accepted change. After this request the test read the settings back and found the user admin with the login form on.
3. Start it again with its port on 127.0.0.1. The login and settings stay in the config folder.
docker rm -f lidarr docker run -d --name lidarr --env-file ~/docker/lidarr/lidarr.env -p 127.0.0.1:PORT:8686 \ -v ~/docker/lidarr/config:/config -v ~/music:/music -v ~/downloads:/downloads \ --restart unless-stopped \ lscr.io/linuxserver/lidarr@sha256:d8549ff9ea29b4015c32257360652c1000c31ea471a2b3f0835ae77292faf35b
--restart unless-stopped brings Lidarr back when your Docker daemon restarts (Rootless DOCKER).
4. Add the proxy fragment as ~/.lighttpd/custom.d/lidarr.conf, with your USERNAME and PORT:
$HTTP["url"] =~ "^/user-USERNAME/lidarr(/|$)" {
auth.require = ()
setenv.set-request-header = ( "Authorization" => "" )
proxy.server = ( "" => ( (
"host" => "127.0.0.1",
"port" => PORT
) ) ),
proxy.header = ( "upgrade" => "enable" )
}
auth.require = () lets requests past your panel login to Lidarr's own login. The setenv.set-request-header line is there to remove your panel login, which a browser logged into your panel sends with every request, before the request reaches Lidarr (Lighttpd Custom Configuration explains the line). Lidarr uses a login form, and its login worked with the line in place; the test did not separately check that the panel login no longer reaches Lidarr. "upgrade" => "enable" lets WebSocket connections through for live updates; the live connection was not tested, and the logged-in page showed no connection warning. Then check the syntax from your home folder:
cd ~ && /usr/sbin/lighttpd -t -f ~/.lighttpd.conf
It prints Syntax OK. Your web server picks the file up within about a minute (Lighttpd Custom Configuration). In the test the address first answered 502 while the container started, then redirected to the login page about 20 seconds after the fragment was saved.
Configure
- Open
https://SERVER/user-USERNAME/lidarr/and log in asadminwith the password fromcat ~/docker/lidarr/login.pw. - Inside the container your music folder is
/music(~/musicon your account) and downloads are/downloads(~/downloads)./musicis the folder to give Lidarr as its root folder; setting up a root folder was not part of the test. To use folders you already have elsewhere, change the left side of the-vlines in step 3, thendocker rm -f lidarrand run step 3 again; that variant was not tested. - Keep Authentication Required on Enabled. Every account on the server can reach the port on
127.0.0.1. - To change the password later, use Lidarr's own settings and keep
login.pwin step with it; that was not tested. - Updating: the digest keeps you on the tested build. To move to a newer one, pull the image, read its digest, then run
docker rm -f lidarrand step 3 with the new digest. The config folder keeps your settings and login. Updating was not tested.
docker pull lscr.io/linuxserver/lidarr:latest
docker image inspect lscr.io/linuxserver/lidarr:latest --format '{{index .RepoDigests 0}}'

Integrate
Connecting indexers, a download client or Prowlarr was not part of the test. Other programs talk to Lidarr with its API key, the LIDARR__AUTH__APIKEY value in ~/docker/lidarr/lidarr.env.
Two measurements from the Bazarr test on the same server bear on this. A container could not reach a program listening on the server's own 127.0.0.1, which is where the apps from Install Media Stack listen. Containers on the same user-defined Docker network did reach each other by name. The Lidarr container in step 3 is not put on such a network. Adding Lidarr to one, and any route from Lidarr to a download client or Prowlarr, was not tested.
Test
docker ps --filter name=lidarrshows the container as Up.https://SERVER/user-USERNAME/lidarr/redirects to Lidarr's login page.stat -c '%a %n' ~/docker/lidarr ~/docker/lidarr/lidarr.env ~/docker/lidarr/login.pwshowed700,600and600in the test.- Requests without a login straight to the port are refused, which is what another account on the server sees:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:PORT/user-USERNAME/lidarr/api/v1/system/status
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:PORT/user-USERNAME/lidarr/
In the test the first returned 401 and the second 302, a redirect to the login page. Through the panel address the results matched, also for a request carrying only the panel login. Of the addresses tried, only /ping answered without a login, with {"status":"OK"}.
Uninstall
docker rm -f lidarr rm -f ~/.lighttpd/custom.d/lidarr.conf touch ~/.lighttpd/custom docker image rm lscr.io/linuxserver/lidarr@sha256:d8549ff9ea29b4015c32257360652c1000c31ea471a2b3f0835ae77292faf35b
Deleting a fragment changes no remaining file, so touch ~/.lighttpd/custom makes your web server restart without it (deleting or disabling a fragment).
Deleting the data is your choice. rm -rf ~/docker/lidarr deletes the login file, the settings file with the API key, and the config folder with Lidarr's database. rmdir ~/music ~/downloads removes those two folders only if they are empty, so music and downloads you keep are not touched. The removals in this section, apart from the touch, were run in the test.
Troubleshooting
- The syntax check prints "cannot change directory" and then a parser error: it was run from another folder. Run
cd ~first; in the test the same file then gaveSyntax OK. - The address answers 502 right after the start: Lidarr was still starting; in the test this cleared by itself. If it stays, check
docker psand that the port in the fragment matches step 3 (the 502 section of Lighttpd Custom Configuration); that case was not seen in the test. - Step 2 prints a code other than
PUT 202: not seen in the test. Treat the login as not set and do not publish the port in step 3. Check thatUSERNAMEis replaced in both addresses and thatlogin.pwexists, then run the step 2 commands from the{ catline again. docker pullordocker runfails before Lidarr starts: see the troubleshooting section of Rootless DOCKER.
Rootless Docker, which this guide runs on, is installed on all Pulsed Media servers (Pulsed Media Seedbox and Storage Features); the seedbox plans list what each includes.
See also
- Self-Hosted Apps on PMSS — more applications for rootless Docker, with their path settings and login defaults
- Install Media Stack — Sonarr, Radarr, Prowlarr and Jellyfin, installed by PMSS
- Lighttpd Custom Configuration — proxy fragments and what each line does
- Rootless DOCKER — running containers in your account
- Seedbox — Pulsed Media seedbox plans