Jump to content

Lidarr on PMSS

From Pulsed Media Wiki

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.

Lidarr sign-in form with Username and Password fields and a green Login button
Lidarr's login page at /user-USERNAME/lidarr/ in the 24 October 2026 test.

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 sets LIDARR__LOG__ANALYTICSENABLED=False; per the source that turns both off. In the test the setting read back as analyticsEnabled: 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 as admin with the password from cat ~/docker/lidarr/login.pw.
  • Inside the container your music folder is /music (~/music on your account) and downloads are /downloads (~/downloads). /music is 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 -v lines in step 3, then docker rm -f lidarr and 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.pw in 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 lidarr and 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}}'
Lidarr library page with an empty library and buttons to add a root folder and a new artist
After logging in: the empty library of a new install, 24 October 2026 test.

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

  1. docker ps --filter name=lidarr shows the container as Up.
  2. https://SERVER/user-USERNAME/lidarr/ redirects to Lidarr's login page.
  3. stat -c '%a %n' ~/docker/lidarr ~/docker/lidarr/lidarr.env ~/docker/lidarr/login.pw showed 700, 600 and 600 in the test.
  4. 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 gave Syntax 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 ps and 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 that USERNAME is replaced in both addresses and that login.pw exists, then run the step 2 commands from the { cat line again.
  • docker pull or docker run fails 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