Skip to main content
  1. Posts/

Master the *arr Stack: Ultimate Self‑Hosted Media Server Guide (2026)

·5 mins

The Community Spark #

In early July 2026 the r/selfhosted front page lit up with a flurry of posts titled “*arr stack on 2 GB VPS?” and “Why my *arr services keep crashing after a month.” Users were wrestling with three intertwined problems: resource constraints, network‑wide automation, and maintenance fatigue. The core question was simple yet profound: *Can a lean VPS reliably run the full arr suite (Sonarr, Radarr, Lidarr, Readarr) and still deliver 4K streaming without constant babysitting?

Synthesized Community Perspectives #

PerspectiveKey PointsConsensus
Performance‑FirstRecommend Alpine‑based Docker images, limit each container to 250 MiB RAM, use unbound DNS caching, and store media on a separate NFS mount.Majority agree that Docker + cgroups is the safest route on low‑end VPS.
Simplicity‑FirstSuggest using a single Ubuntu 22.04 LTS VM with systemd services; easier for newcomers, fewer networking layers.Accepted for users who prefer “one‑command install” scripts (e.g., linuxserver/arr).
Automation‑FirstPush for bazarr (subtitles) and prowlarr (indexer aggregation) to reduce manual indexer tweaking.Recognized as value‑add, but community warns about extra CPU load.
Security‑FirstEmphasize reverse‑proxy with Caddy, automatic TLS via Let’s Encrypt, and fail2ban for SSH brute‑force.Universally endorsed; many share pre‑written Caddyfile snippets.

The debate settled around a hybrid approach: Docker for isolation, a minimal reverse‑proxy for TLS, and selective addition of auxiliary services only when resources permit.

Deep‑Dive Actionable Guide #

Below is a step‑by‑step recipe that reflects the “Performance‑First” consensus while keeping the “Simplicity‑First” spirit.

1. Provision a VPS #

# Example: Hetzner CX11 (2 vCPU, 4 GB RAM, 80 GB SSD)
ssh root@<VPS_IP>
apt update && apt upgrade -y

2. Install Docker & Docker‑Compose #

apt install -y ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable docker

3. Create a Shared Media Volume #

mkdir -p /mnt/media/{downloads,library}
chown -R 1000:1000 /mnt/media   # Docker's default user

4. Define docker-compose.yml #

version: "3.8"
services:
  sonarr:
    image: ghcr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /mnt/media:/media
      - ./config/sonarr:/config
    ports:
      - "8989:8989"
    restart: unless-stopped
    mem_limit: 256m

  radarr:
    image: ghcr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /mnt/media:/media
      - ./config/radarr:/config
    ports:
      - "7878:7878"
    restart: unless-stopped
    mem_limit: 256m

  lidarr:
    image: ghcr.io/linuxserver/lidarr:latest
    container_name: lidarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /mnt/media:/media
      - ./config/lidarr:/config
    ports:
      - "8686:8686"
    restart: unless-stopped
    mem_limit: 256m

  readarr:
    image: ghcr.io/linuxserver/readarr:latest
    container_name: readarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /mnt/media:/media
      - ./config/readarr:/config
    ports:
      - "8787:8787"
    restart: unless-stopped
    mem_limit: 256m

  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

5. Add a Minimal Caddyfile #

{
    email admin@example.com
    automatic_https {
        on_demand
    }
}

sonarr.example.com {
    reverse_proxy sonarr:8989
}
radarr.example.com {
    reverse_proxy radarr:7878
}
lidarr.example.com {
    reverse_proxy lidarr:8686
}
readarr.example.com {
    reverse_proxy readarr:8787
}

Replace example.com with your domain and point DNS A records to the VPS IP.

6. Launch Everything #

docker compose up -d
docker compose ps   # Verify all containers are healthy

7. Fine‑Tune Indexers & Quality Profiles #

  • Inside each *arr UI, import a Prowlarr indexer list (JSON) shared by the r/selfhosted community – it bundles Jackett‑compatible sources that respect 4K limits.
  • Set Download Client to qBittorrent running in a separate Docker container, limited to 1 GiB/s to protect the VPS bandwidth.

8. Automate Backups (Weekly) #

0 3 * * 0 tar -czf /backup/arr-config-$(date +%F).tar.gz /path/to/config

Pros & Cons Comparison #

SolutionProsCons
Docker‑Isolation (LinuxServer images)Predictable memory caps, easy updates, community‑tested healthchecksSlight learning curve for Docker Compose
Bare‑Metal Ubuntu Systemd ServicesOne‑liner installers, minimal overheadHarder to enforce per‑service limits; updates may break dependencies
*Full arr + Prowlarr + Bazarr + JackettEnd‑to‑end automation (subtitles, indexer federation)Additional ~150 MiB RAM each; may exceed 2 GB VPS
Caddy Reverse‑ProxyAutomatic HTTPS, low CPU, simple configRequires a valid domain; some ISPs block port 443 on residential IPs

The Verdict / Expert Advice #

  • Newbies (≤ 2 GB VPS): Stick to the Docker stack above, omit Bazarr and Prowlarr initially. Add them later once you confirm stable RAM usage.
  • Power Users (≥ 4 GB VPS): Deploy the full suite, enable unbound DNS caching, and run qBittorrent in its own container with --net=host for maximum throughput.
  • Security‑Conscious: Keep the Caddyfile minimal, enable http3 (supported in Caddy v2.7+), and schedule docker system prune -a weekly to eliminate orphaned layers.

By following this community‑validated blueprint, you’ll achieve a responsive, low‑maintenance *arr stack that survives VPS restarts and scaling bumps—exactly what r/selfhosted members have been shouting about.

Frequently Asked Questions (FAQ) #

*Q1: Can I run the arr stack on a 1 CPU, 2 GB RAM VPS without crashes?
A1: Yes, if you limit each container to ≤ 256 MiB RAM, use Alpine‑based images, and avoid heavy add‑ons like Bazarr. Monitoring with docker stats helps you stay within the quota.

*Q2: Do I need a separate download client, or can the arr apps download directly?
A2: While *arr can invoke aria2c, the community recommends a dedicated torrent client (qBittorrent or Transmission) in its own container for better queue handling and UI separation.

*Q3: How do I secure my arr UI from the public internet?
A3: Caddy automatically provisions TLS. Additionally, enable basic auth in each service’s settings and restrict access to known IPs via a Caddy @allowed_ips matcher.

Q4: What’s the best backup strategy for configuration data?
A4: Bind-mount the /config directories (as shown) and schedule a weekly tar.gz of the ./config folder to an off‑site location (e.g., Backblaze B2 or another VPS). Verify backups by restoring to a test container monthly.