Install Media Stack
The install-media-stack script sets up a complete media automation stack on a Pulsed Media seedbox. It installs seven applications in your home directory, binds them to localhost, assigns randomized ports, turns on a login with a generated password for every web app, and configures a lighttpd reverse proxy so you can reach everything over HTTPS. The welcome tab of the seedbox panel has an Install Media Stack button that runs it without SSH.
No root access needed. The account needs at least 1024 MiB of memory (see Memory requirement).
What it installs
| Application | Purpose | Access |
|---|---|---|
| Radarr | Automated movie downloads | https://SERVER/public-USER/radarr/
|
| Sonarr | Automated TV show downloads | https://SERVER/public-USER/sonarr/
|
| Prowlarr | Indexer manager (feeds Radarr/Sonarr) | https://SERVER/public-USER/prowlarr/
|
| Jellyfin | Media streaming server | https://SERVER/public-USER/jellyfin/
|
| SABnzbd | Usenet downloader | https://SERVER/public-USER/sabnzbd/
|
| Autobrr | Grabs new releases from IRC announce channels and feeds, then hands them to your download client | https://SERVER/public-USER/autobrr/
|
| Cloudplow | Cloud storage upload automation | CLI only (tmux session) |
All applications run under your user account. All bind to 127.0.0.1 only, so they are not directly accessible from the internet. The lighttpd reverse proxy handles HTTPS; each web app's own login controls who gets in (see Security).
How to install
From the seedbox panel
On the welcome tab, press Install Media Stack. The installer runs as your account, no SSH client needed, and the generated logins are saved to ~/.media-stack-credentials.txt. The button covers the first install only: once ~/.bin has content or Jellyfin data exists, it is disabled and reruns go over SSH, so you can review what is already there before anything is replaced.
Quick install over SSH
Download the script and run it:
wget -q https://raw.githubusercontent.com/MagnaCapax/PMSS/refs/heads/main/etc/skel/install-media-stack.sh bash install-media-stack.sh
The script runs the copy on your server, which PMSS keeps current with each platform update. To fetch the newest version from GitHub before installing, add --self-update.
If the script is already on your server
On newer PM servers, the script may already be in your home directory:
bash ~/install-media-stack.sh
Dry run (verify before installing)
To see what the script will do without making any changes:
bash install-media-stack.sh --dry-run
This checks all download URLs, reports CPU architecture and GLIBC version, and shows the planned actions.
Memory requirement
The full stack needs about 900 MB of RAM. Before installing, the script reads your account's memory limit. Below 1024 MiB it warns and stops. The panel button never overrides this. Over SSH, --force installs anyway, but on a small account the throttling can leave rTorrent and the panel unresponsive. A larger plan is the better fix.
How it works
Installation layout
Everything goes under your home directory:
| Path | Contents |
|---|---|
~/.bin/ |
Application binaries (Radarr, Sonarr, Prowlarr, Jellyfin, .NET runtime) |
~/.config/ |
Per-application configuration and databases |
~/.install-media-stack.log |
Installation log |
~/.media-stack-credentials.txt |
Generated app logins (file mode 600, readable only by you) |
Port assignment
Each application gets a randomized port between 10000 and 65000. The script tests that the port is free before binding. Ports are stored in each application's config file. If you reinstall, the same ports are reused from existing configs.
Reverse proxy
The script generates a lighttpd configuration snippet that maps each application to a URL path under your seedbox web panel. For example, if your seedbox URL is https://server.pulsedmedia.com/user-alice/, Radarr becomes accessible at https://server.pulsedmedia.com/public-alice/radarr/.
tmux sessions
The script creates shell aliases that launch each application in a named tmux session:
radarr # starts Radarr in tmux session 'radarr' sonarr # starts Sonarr in tmux session 'sonarr' prowlarr # starts Prowlarr in tmux session 'prowlarr' jellyfin # starts Jellyfin in tmux session 'jellyfin' sabnzbd # starts SABnzbd in tmux session 'sabnzbd' autobrr # starts Autobrr in tmux session 'autobrr'
To view a running session: tmux attach -t radarr
To detach without stopping: Ctrl+B then D
CLI options
| Option | Description |
|---|---|
--self-update |
Fetch the newest installer from GitHub and run that (off by default) |
--skip-update |
No effect; kept so older instructions still work |
--dry-run |
Show planned actions without making changes |
--verify-only |
Only verify download URLs, then exit |
--force |
Install below the 1024 MiB memory guard (SSH only) |
--start-stopped |
Start installed apps that are not running, then exit |
--secure-app=APP |
Set up the default login for one installed app, then exit |
--uninstall |
Remove the PMSS-managed media stack from your account |
--autobrr-url=URL |
Use a specific Autobrr download URL |
--sonarr-url=URL |
Use a specific Sonarr download URL |
--sonarr-branch=BR |
Sonarr branch (default: main)
|
--radarr-url=URL |
Use a specific Radarr download URL |
--radarr-branch=BR |
Radarr branch (default: master)
|
--radarr-version=TAG |
Pin Radarr to a specific version |
--prowlarr-url=URL |
Use a specific Prowlarr download URL |
--prowlarr-branch=BR |
Prowlarr branch (default: master)
|
--jellyfin-url=URL |
Use a specific Jellyfin download URL |
--jellyfin-ffmpeg=PATH |
Path to custom ffmpeg binary for Jellyfin |
--sab-url=URL |
Use a specific SABnzbd download URL |
Compatibility
| Debian version | Status | Notes |
|---|---|---|
| Debian 13 (Trixie) | Supported | Full support, .NET 8 |
| Debian 12 (Bookworm) | Supported | Full support, .NET 8 |
| Debian 11 (Bullseye) | Supported | .NET 8, Radarr GLIBC fallback if needed. Jellyfin needs a user-supplied ffmpeg 4.4+ |
| Debian 10 (Buster) | Supported | .NET 8, Radarr pinned to v5.10.4 (GLIBC 2.28) |
On older systems where GLIBC is below 2.33, the script automatically pins Radarr to v5.10.4.9218 to avoid sqlite/GLIBC loader errors.
Jellyfin needs FFmpeg 4.4 or newer to start. Where the system ffmpeg is older, as on Debian 11, the script skips Jellyfin and prints how to fix it: put a static ffmpeg build in ~/.bin and rerun with --jellyfin-ffmpeg=$HOME/.bin/ffmpeg.
CPU architecture
The script detects x86_64, ARM64, and ARM architectures. On x86_64 it also checks for SSE4.2 and AVX support (Jellyfin benefits from SSE4.2 for software transcoding).
The *ARR workflow
Once installed, the typical automation flow is:
Prowlarr (indexer manager)
|
+-- feeds indexers to --> Radarr (movies)
| |
| +-- sends to torrent client (rTorrent/Deluge/qBittorrent)
| |
| +-- post-import --> Jellyfin library
|
+-- feeds indexers to --> Sonarr (TV shows)
|
+-- sends to torrent client
|
+-- post-import --> Jellyfin library
1. Prowlarr manages your indexer connections (torrent trackers, Usenet indexers) and feeds them to Radarr and Sonarr. 2. Radarr and Sonarr monitor your wanted movies/shows, search indexers via Prowlarr, and send downloads to your torrent client. 3. Your torrent client (rTorrent, Deluge, or qBittorrent) downloads the files. 4. Radarr/Sonarr detect the completed download, rename/organize the files, and update your Jellyfin library. 5. Stream from Jellyfin on any device.
Security
The installer follows these security principles:
- Login on every app — the installer creates a login for each web app and writes the passwords to
~/.media-stack-credentials.txt(mode 600) - Localhost binding only — all applications listen on
127.0.0.1, not on public interfaces - Randomized ports — each user gets different ports, reducing collision and enumeration risk
- HTTPS via reverse proxy — lighttpd handles TLS, so all access is encrypted
- No root required — everything runs in user space
- Checksum verification — downloaded archives are verified with SHA256
Application-level authentication
Media stack applications are served under the /public-USERNAME/ URL path, which has no proxy-level password gate. This path exists so seedbox users can host websites, share files, and run public-facing services. Each application's own login is what protects it, and the installer sets that login up before the proxy goes live.
| Application | Login set up by the installer | What you need to do |
|---|---|---|
| Jellyfin | Admin account created through Jellyfin's startup API | Log in with the credentials from ~/.media-stack-credentials.txt
|
| Radarr | Forms login enabled | Same |
| Sonarr | Forms login enabled | Same |
| Prowlarr | Forms login enabled | Same |
| SABnzbd | Username and password set in its config | Same |
| Autobrr | Admin user created | Same |
On a rerun, the installer keeps any login you already set rather than overwriting the password.
The welcome tab lists each installed app with a Protected or Exposed badge. Exposed means the panel found no login configured for that app, so anyone with the URL can open it. The Secure this app button next to an exposed app runs install-media-stack.sh --secure-app=APP as your account and adds the new login to the credentials file. Media Stack Exposed and Protected Status explains the badges in detail.
PMSS checks the media stack apps every two minutes and records which ones are running. Apps that keep failing are reported, not restarted in a loop: check the app log, then use Start stopped apps on the welcome tab or --start-stopped over SSH.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Install stops with a low-memory warning | Account memory limit below 1024 MiB | Use a larger plan. --force over SSH overrides the guard, at the cost of a sluggish account.
|
| Setup stops at the authentication step | The installer could not set an app's login, so it stops before starting the stack | Open a support ticket and include ~/.install-media-stack.log.
|
| An app shows Exposed | No login configured for that app | Press Secure this app on the welcome tab, or run bash ~/install-media-stack.sh --secure-app=APP.
|
| Application does not start | Port already in use | Check ss -tlnp for conflicts. Remove config and reinstall to get new port.
|
| 502 Bad Gateway in browser | Application not running | Start it: radarr (or sonarr, etc.). Check tmux session.
|
| Radarr crashes on startup | GLIBC too old (Debian 10/11) | Script should auto-detect. If not, use --radarr-version=v5.10.4.9218.
|
| Jellyfin transcoding fails | No hardware transcoding on shared | Software transcoding works. For hardware transcoding, use a dedicated server with iGPU. |
| SABnzbd fails to start | Python venv missing | Run python3 -m venv ~/.config/sabnzbd/venv then reinstall.
|
| "Permission denied" errors | Quota exceeded | Check disk usage. Free space and retry. |
| Applications show old version | The installer turns off the built-in updaters of Radarr, Sonarr and Prowlarr | Rerun bash ~/install-media-stack.sh over SSH; it updates the apps in place.
|
| Jellyfin missing after install | System ffmpeg older than 4.4 | See Compatibility: supply a static ffmpeg with --jellyfin-ffmpeg.
|
Source code
The installer script is open source, part of PMSS:
- Script: install-media-stack.sh on GitHub
- Documentation: install-media-stack.md on GitHub
See also
- Jellyfin — streaming media from your seedbox
- Media Stack Exposed and Protected Status — what the panel badges mean and how to secure an app
- Seedbox for Plex and Jellyfin — media server comparison
- RTorrent vs qBittorrent vs Deluge — torrent client comparison
- PM Software Stack — the full PMSS documentation