Jump to content

InfiniDysk on PMSS

From Pulsed Media Wiki

InfiniDysk streams files from your own Usenet provider through a WebDAV share instead of downloading complete files to your Pulsed Media seedbox first, and it is served at your own panel address behind its own login. It runs in rootless Docker inside your account and describes itself as a drop-in replacement for nzbdav 0.6.4. Tested on one Pulsed Media seedbox on 24 October 2026 with InfiniDysk 1.6.3, built from source; the parts that were not tested are marked where they appear.

Privacy

Level: MEDIUM. Using InfiniDysk reduces your privacy. Your Usenet provider, an outside company you choose, receives every article request InfiniDysk makes for you, and an indexer you add sees your searches. The provider's login is stored in InfiniDysk's settings under ~/docker/infinidysk/config, in your account on a shared server; the steps below make that folder readable only by you.

Requirements

Need InfiniDysk on PMSS
Memory About 0.4 GB resident inside the container, measured in the test with no Usenet provider connected.
Image The published image does not run under a URL path. It is built with an empty URL base, and setting NZBDAV_URL_BASE when the container starts makes it stop with a URL base mismatch and restart in a loop. An image that runs at /user-USERNAME/infinidysk/ has to be built from source with that value as a build argument (step 3).
File quota The build creates many small files. In the test account (file limit 100,000 soft, 125,000 hard) the build cache reached 96,000 to 107,000 files and the build stopped with "Disk quota exceeded". After other images were removed and docker builder prune -af ran, usage fell to about 20,000 files and the build finished. The cache from one build was 3.46 GB.
Own login Yes. The admin login is created before any port is published. The WebDAV share has a separate login.
Address https://SERVER/user-USERNAME/infinidysk/ through your own web server. rclone uses a second port on 127.0.0.1.
Other apps A Usenet provider account of your own. rclone, which is already installed on the server, to reach the share as files.

Install

Replace USERNAME with your account name. PORT (the web interface) and PORT2 (the WebDAV share for rclone) are two free ports between 2000 and 38000 that ss -tln does not list. Other accounts on the same server can connect to 127.0.0.1, so the admin and WebDAV logins are set while no port is published.

1. Check your file count. quota -s shows files used and the limit. If you are close to it, remove images you no longer use with docker rmi first.

2. Get the source of release 1.6.3. The submodule step is required; without it the build stops at the rapidyenc step.

mkdir -p ~/docker/src && cd ~/docker/src
git clone --depth 1 --branch v1.6.3 https://github.com/infinidysk/infinidysk.git
cd infinidysk && git submodule update --init --depth 1

3. Build the image for your path, then clear the build cache. docker builder prune -af deletes all build cache in your account, including any other builds.

cd ~/docker/src/infinidysk
docker build -t infinidysk:1.6.3-subpath --build-arg NZBDAV_URL_BASE=/user-USERNAME/infinidysk .
docker builder prune -af

4. Make the folders and the passwords. The passwords stay in files only you can read. tr removes the trailing newline, because curl sends a password file exactly as it is.

mkdir -p ~/docker/infinidysk/config ~/docker/infinidysk/secrets
chmod 700 ~/docker/infinidysk
openssl rand -base64 24 | tr -d '/+=\n' > ~/docker/infinidysk/secrets/admin.pw
openssl rand -base64 24 | tr -d '/+=\n' > ~/docker/infinidysk/secrets/dav.pw
printf '{"webdav.user":"dav","webdav.pass":"%s"}' "$(cat ~/docker/infinidysk/secrets/dav.pw)" > ~/docker/infinidysk/secrets/dav.json
printf 'PUID=0\nPGID=0\nTZ=Etc/UTC\n' > ~/docker/infinidysk/app.env
chmod 600 ~/docker/infinidysk/secrets/* ~/docker/infinidysk/app.env

5. Start it once with no port published. The secrets folder is mapped in read-only for the next step.

docker run -d --name infinidysk --env-file ~/docker/infinidysk/app.env \
  -v ~/docker/infinidysk/config:/config \
  -v ~/docker/infinidysk/secrets:/secrets:ro \
  infinidysk:1.6.3-subpath
docker logs infinidysk 2>&1 | grep 'Backend is healthy'

Repeat the last command until it prints Backend is healthy.

6. Create the admin and the WebDAV login from inside the container. The image includes curl.

docker exec infinidysk curl -s -c /tmp/setup.cookies -o /dev/null -w 'admin: %{http_code}\n' \
  -X POST http://127.0.0.1:3000/user-USERNAME/infinidysk/onboarding \
  --data-urlencode username=admin \
  --data-urlencode password@/secrets/admin.pw \
  --data-urlencode confirmPassword@/secrets/admin.pw
docker exec infinidysk curl -s -b /tmp/setup.cookies -o /dev/null -w 'webdav: %{http_code}\n' \
  -X POST http://127.0.0.1:3000/user-USERNAME/infinidysk/settings/update \
  --data-urlencode config@/secrets/dav.json
docker exec infinidysk rm -f /tmp/setup.cookies

In the test the same two requests returned 302 (admin created) and 200 (WebDAV login saved). They were sent to a published loopback port on an image built without a path, and that config folder was then reused by the path build; this exact in-container form was not run.

7. Start it with its ports. Leave out -p 127.0.0.1:PORT2:8080 if you will not use rclone.

docker rm -f infinidysk
docker run -d --name infinidysk --restart unless-stopped --env-file ~/docker/infinidysk/app.env \
  -p 127.0.0.1:PORT:3000 -p 127.0.0.1:PORT2:8080 \
  -v ~/docker/infinidysk/config:/config \
  infinidysk:1.6.3-subpath

8. Add the proxy fragment as ~/.lighttpd/custom.d/infinidysk.conf, with your USERNAME and PORT. The path is already built into the image, so there is no map-urlpath. The setenv.set-request-header line keeps your panel login, which a browser logged into your panel sends with every request, from reaching InfiniDysk.

$HTTP["url"] =~ "^/user-USERNAME/infinidysk/" {
  auth.require = ()
  setenv.set-request-header = ( "Authorization" => "" )
  proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => PORT ) ) )
  proxy.header = ( "upgrade" => "enable" )
}

Check the syntax with /usr/sbin/lighttpd -t -f ~/.lighttpd.conf. Your web server picks up the file within about two minutes.

Configure

  • Log in at https://SERVER/user-USERNAME/infinidysk/ as admin, with the password from cat ~/docker/infinidysk/secrets/admin.pw, and add your Usenet provider under Settings → Usenet. No provider was connected in the test.
  • The WebDAV login (user dav, password in secrets/dav.pw) is separate from the admin login; the admin login is refused on the share. It can be changed under Settings → WebDAV.
  • Never set DISABLE_WEBDAV_AUTH. It switches the WebDAV login off, and every account on the server can reach the share's port.

Integrate

rclone reads the share on the second port, PORT2. Through the panel address the share lists its entries without the path, so rclone pointed there shows an empty folder. Write the rclone config with the password read from its file:

cat > ~/docker/infinidysk/rclone.conf <<EOF
[infinidysk]
type = webdav
url = http://127.0.0.1:PORT2/
vendor = other
user = dav
pass = $(rclone obscure - < ~/docker/infinidysk/secrets/dav.pw)
EOF
chmod 600 ~/docker/infinidysk/rclone.conf
rclone --config ~/docker/infinidysk/rclone.conf lsf infinidysk:

In the test this listed .ids/, README, completed-symlinks/, content/ and nzbs/, and content held the folders audio, movies, software and tv.

InfiniDysk also has a SABnzbd-compatible API, so Sonarr and Radarr can use it as a download client and import through rclone symlinks or STRM files, according to the InfiniDysk documentation. That route, an rclone mount of the share, and playback were not tested end to end: the test had no Usenet provider.

Test

  1. docker ps --filter name=infinidysk shows the container as Up. In the test the path build was removed after about 55 seconds with no restarts, so the 60-second check was not completed on it.
  2. https://SERVER/user-USERNAME/infinidysk/ shows the InfiniDysk login page.
  3. Requests without a login straight to the ports 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/infinidysk/api/get-config
curl -s -o /dev/null -w '%{http_code}\n' -X PROPFIND http://127.0.0.1:PORT2/

Both returned 401 in the test. Through the panel address, an anonymous request for the overview page was redirected to the login page and an anonymous WebDAV request got 401.

The InfiniDysk login page at /user-USERNAME/infinidysk/ in the 24 October 2026 test.

Uninstall

docker rm -f infinidysk
rm ~/.lighttpd/custom.d/infinidysk.conf
touch ~/.lighttpd/custom
docker rmi infinidysk:1.6.3-subpath

Deleting a fragment changes no remaining file, so touch ~/.lighttpd/custom makes your web server restart without it within a minute or two (Lighttpd Custom Configuration explains why).

Deleting the data is your choice. rm -rf ~/docker/infinidysk deletes InfiniDysk's settings, including your provider login, its database, the passwords and the rclone config. rm -rf ~/docker/src/infinidysk deletes the source checkout.

Troubleshooting

  • The container restarts in a loop and its log mentions a URL base mismatch: NZBDAV_URL_BASE was set at start on an image built without a path. Build the image as in step 3.
  • The login page loads without styling and with a broken logo: an image built without a path is behind a fragment with map-urlpath. Its links point at /assets/ on the server root. Use the path build from step 3.
  • The build stops at the rapidyenc step: run git submodule update --init --depth 1 in the source folder and build again.
  • The build stops with "Disk quota exceeded" (errno -122): the file limit is reached. Remove unused images, run docker builder prune -af and build again.
  • rclone lists nothing: point it at PORT2, not at the panel address.
  • The share refuses your login: use the WebDAV login, not the admin login.
  • The admin login is refused with the right password: a password file made some other way may end in a newline, which curl sends as part of the password. Make the files as in step 4.

See also