Skip to content

abarbarich/arrstack

Repository files navigation

ArrStack

*The whole arr media stack as one Docker Compose project — with a one-command Proxmox installer.

Sonarr, Radarr, Lidarr, Prowlarr, Bazarr, qBittorrent, FlareSolverr and Jellyseerr, wired to a single hardlink-friendly /data tree, behind an optional reverse proxy, with an optional VPN kill-switch for the torrent client. Run it on a fresh Proxmox LXC with one command, or docker compose up -d on any Docker host.


Two ways to install

A) Proxmox VE — one command on the host

bash -c "$(curl -fsSL https://raw.githubusercontent.com/abarbarich/arrstack/main/arrstack.sh)"

Run it on your Proxmox host as root. It will:

  1. create a Debian 12 LXC (unprivileged, nesting=1 so Docker works),
  2. optionally format a spare disk as ext4 and bind-mount it as the media store,
  3. install Docker + the Compose plugin inside the container,
  4. drop the stack in /opt/arrstack, generate .env, and docker compose up -d,
  5. print every app's URL.

With a terminal you get a whiptail menu (resources, network, storage, VPN); add -y to take defaults from the environment for a fully unattended run.

B) Any Docker host — plain Compose

git clone https://github.com/abarbarich/arrstack.git
cd arrstack
cp .env.example .env      # edit PUID/PGID/TZ and DATA_ROOT
docker compose up -d

What it installs

App Port Role
Sonarr 8989 TV
Radarr 7878 Movies
Lidarr 8686 Music
Prowlarr 9696 Indexer manager — syncs indexers to the *arr apps
FlareSolverr 8191 Solves Cloudflare/JS challenges for some indexers
Bazarr 6767 Subtitles
qBittorrent 8080 Torrent download client
Jellyseerr 5055 Requests (feeds Sonarr/Radarr; talks to Jellyfin/Plex/Emby)
Caddy 80/443 Optional reverse proxy for http://<app>.home names
gluetun Optional VPN sidecar; routes qBittorrent through WireGuard/OpenVPN

All apps are official LinuxServer.io images (Jellyseerr uses the maintained seerr-team/seerr image). There is no separate media server here — ArrStack is happy to feed an external Jellyfin/Plex (see the Caddyfile for a jellyfin.home example).

Replaces Jackett. Prowlarr is the modern indexer manager and supersedes Jackett for every *arr app, so Jackett is not included.


Requirements

  • Docker Engine + Compose v2 (the Proxmox installer sets these up for you).
  • For the Proxmox path: Proxmox VE 8.x (uses pct/pveam/pvesh).
  • ~2 GB RAM is plenty (no build steps — everything is a prebuilt image); the Proxmox CT defaults to 4 GB for headroom.
  • Storage on one filesystem for the whole /data tree, so hardlinks work.

Media storage & the /data layout

Every container sees a single tree so hardlinks and atomic moves work between the download client and the libraries (the TRaSH Guides layout). Copying is avoided entirely — an import is instant and uses no extra space.

/data
├── media/{movies,tv,music}                 # Sonarr/Radarr/Lidarr libraries
└── torrents/{...,incomplete}               # qBittorrent downloads

DATA_ROOT in .env points at the host location of this tree.

Formatting + mounting a disk on Proxmox

scripts/setup-storage.sh (run on the host) formats a blank disk as ext4, adds it to /etc/fstab by UUID, and bind-mounts it into the CT — with the right ownership for an unprivileged container (in-CT UID 1000 → host 101000):

# interactive: lists only SAFE, blank disks (hides the OS disk + mounted/LVM/ZFS)
scripts/setup-storage.sh --ctid 111

# non-interactive: format a specific disk
scripts/setup-storage.sh --ctid 111 --disk /dev/sdb -y

# or bind an existing directory instead of formatting anything
scripts/setup-storage.sh --ctid 111 --existing /tank/media

It refuses to touch the OS disk or anything mounted / part of LVM/ZFS/RAID, and requires you to type the device path to confirm the (destructive) format.


VPN for qBittorrent (optional)

Route only qBittorrent through a gluetun tunnel. If the VPN drops, gluetun's firewall kills torrent traffic — no leaks — while the rest of the stack keeps working on the LAN.

  1. Fill the VPN_* block in .env (provider, WireGuard key, …).
  2. Enable the overlay — either set in .env:
    COMPOSE_FILE=docker-compose.yml:docker-compose.vpn.yml
    …or pass both files: docker compose -f docker-compose.yml -f docker-compose.vpn.yml up -d (the Proxmox installer does this for you with --vpn).
  3. Verify your exit IP:
    docker exec gluetun wget -qO- https://ipinfo.io/ip

Provider-specific values live in the gluetun wiki.


Configuration (.env)

Variable Default Notes
PUID / PGID 1000 UID/GID that owns the media tree
UMASK 002 group-writable new files (shared media user)
TZ Etc/UTC IANA timezone, e.g. Pacific/Auckland
DATA_ROOT ./data host path of the single /data tree
CONFIG_ROOT ./config where each app stores its config/db
COMPOSE_FILE set to enable the VPN overlay (see above)
VPN_SERVICE_PROVIDER mullvad gluetun provider name
VPN_TYPE wireguard wireguard or openvpn
WIREGUARD_PRIVATE_KEY / WIREGUARD_ADDRESSES WireGuard creds
VPN_SERVER_COUNTRIES optional server pin
LAN_SUBNET 192.168.0.0/16 lets the LAN reach the WebUI through gluetun

After install — wire the apps together

The stack is running, but the apps don't know about each other yet. The step-by-step wiring guide with screenshots is in docs/SETUP.md — Prowlarr indexers + FlareSolverr, syncing indexers to the *arr apps, adding qBittorrent as the download client, root folders, categories, Bazarr and Jellyseerr. It's all localhost/container-name wiring inside one stack.


Updating

Two things update independently: the apps (Docker images) and ArrStack itself (the compose files / scripts). On Proxmox, pct enter <ctid> first.

Update the apps (the everyday case)

cd /opt/arrstack
docker compose pull      # fetch newer images
docker compose up -d     # recreate only the containers that changed
docker image prune -f    # optional: reclaim old image layers

Each app's config/database lives in the CONFIG_ROOT volumes, so nothing is lost on recreate. With Docker the image is the version — pulling a newer image is the update, so ignore the *arr apps' built-in "Updates" screen.

Update ArrStack itself (only when the repo changes)

The Proxmox one-liner installs /opt/arrstack as a git clone:

cd /opt/arrstack
git pull
docker compose up -d

Only needed when the compose file or scripts change upstream — not day to day. (If you didn't install from a clone, just re-fetch the files or re-run the installer.)

Notes

  • VPN users: nothing extra — COMPOSE_FILE in .env means every docker compose command already includes the gluetun overlay.
  • Rollback: if a :latest image regresses, pin that service to a known-good tag (e.g. image: lscr.io/linuxserver/sonarr:4.0.9) and docker compose up -d.
  • Back up first: the config volumes are the only state worth keeping — tar czf arrstack-config.tgz -C "$CONFIG_ROOT" . before a big jump.
  • Hands-off auto-updates: add a Watchtower container to pull + recreate on a schedule — trades control for convenience.

Security

These apps ship with no authentication until you set it in each one. Don't expose the container to the internet directly — keep it behind your firewall and reach it over VPN/Tailscale, or front it with an authenticated reverse proxy. Set a WebUI login in each app after first launch.


How it works

arrstack.sh              # PVE host: create LXC, storage, install Docker, deploy
scripts/setup-storage.sh # PVE host: format ext4 disk + bind-mount into the CT
docker-compose.yml       # the stack
docker-compose.vpn.yml   # optional gluetun overlay (routes qBittorrent)
.env.example             # all configuration
caddy/Caddyfile          # reverse proxy for *.home names
docs/SETUP.md            # the app-wiring walkthrough
lib/helpers.sh           # shared logging / helpers for the host scripts

License

MIT. Provided as-is — review the scripts before running them as root.

About

Single-CT Proxmox installer for the *arr media stack (Sonarr/Radarr/Lidarr/Prowlarr/Jackett/Bazarr/Jellyseerr/qBittorrent + optional Jellyfin/Plex) — no Docker, no per-app container sprawl

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages