Skip to content
victorobahorPublic

About

A premium, VPN-secured Docker Compose media stack using a hybrid local storage and Real-Debrid symlink workflow (Plex, qBittorrent, Gluetun, Decypharr, and the Arr Suite).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎬 ArrStack Media Server Deployment Guide

A premium, fully-parameterized Docker Compose stack for deploying a self-hosted media server containing Plex, qBittorrent (VPN secured), and the Arr Suite (radarr, sonarr, plusarr, prowlarr, decypharr, flaresolverr, gluetun).


🌐 Network Architecture

To optimize performance and ease of use, this stack uses a hybrid network topology:

  • Plex (Macvlan): Placed directly on your local network (my_macvlan_net) with a static IP. This enables native DLNA/local discovery and direct, unthrottled media streaming without traversing Docker bridge routing.
  • Arr Suite (Internal Bridge): Isolated within a custom private network (arr_net). The containers communicate securely via service names (e.g., http://radarr:7878), while their user interfaces are safely mapped to individual host ports.
graph TD
    subgraph Host Storage
        DATA_ROOT["/volume1/portainer (DATA_ROOT)"]
        SSD_CONF["/volume2/SSD/docker (DOCKER_CONFIG_DIR)"]
    end

    subgraph Container Networking [arr_net]
        direction TB
        subgraph Internal Bridge 
            radarr[Radarr]
            sonarr[Sonarr]
            prowlarr[Prowlarr]
            decypharr[Decypharr]
            gluetun[Gluetun VPN]
            qbittorrent[qBittorrent]
            pulsarr[Pulsarr]
        end
        subgraph Local Network
            plex[Plex - Static IP on Macvlan]
        end
    end

    %% Storage connections
    DATA_ROOT -->|Mapped as /data| plex
    DATA_ROOT -->|Mapped as /data| radarr
    DATA_ROOT -->|Mapped as /data| sonarr
    DATA_ROOT -->|Mapped as /data| qbittorrent
    
    DATA_ROOT -->|decypharr_mnt Mapped as /mnt:rshared| decypharr
    DATA_ROOT -->|decypharr_mnt Mapped as /mnt:rslave| plex
    DATA_ROOT -->|decypharr_mnt Mapped as /mnt:rslave| radarr
    DATA_ROOT -->|decypharr_mnt Mapped as /mnt:rslave| sonarr

    %% VPN routing
    qbittorrent -->|network_mode| gluetun
    gluetun -->|All traffic encrypted| WAN((Internet))
    decypharr -->|Direct HTTPS| RD((Real-Debrid))

    %% Automation & Indexing flows
    pulsarr -->|watches playlist| plex
    prowlarr -->|supplies index| radarr
    prowlarr -->|supplies index| sonarr
Loading

πŸ› οΈ Step-by-Step Deployment Guide

Follow these steps sequentially to prepare your host system, configure environment variables, and launch the media stack.

Step 1: Create Host Directory Structure

Before deploying, make sure the directories for container storage and configurations exist on your host system (e.g., Synology NAS, OMV, or generic Linux server).

Create the following directories on your host:

# Configuration & Application Data directory (usually on SSD for performance)
# Note: Plex transcoder uses RAM (/dev/shm) and does not require an SSD directory
mkdir -p /volume2/SSD/docker/decypharr/config
mkdir -p /volume2/SSD/docker/radarr/data
mkdir -p /volume2/SSD/docker/sonarr/data
mkdir -p /volume2/SSD/docker/pulsarr/data
mkdir -p /volume2/SSD/docker/prowlarr/data
mkdir -p /volume2/SSD/docker/flaresolver
mkdir -p /volume2/SSD/docker/qbittorrent

# Shared Media & Downloads directory (usually on high-capacity HDD storage)
mkdir -p /volume1/portainer/torrent/download
mkdir -p /volume1/portainer/torrent/decypharr_mnt
mkdir -p /volume1/portainer/Plex/media/Movies
mkdir -p /volume1/portainer/Plex/media/TvShows

Step 2: Fix Media Permissions

Docker containers run with specific user accounts (PUID=1000, PGID=10 by default). You must assign correct ownership and write permissions on the host system to prevent "Permission Denied" errors in Plex or the Arr suite:

# Assign ownership of the media libraries to PUID 1000 / PGID 10
sudo chown -R 1000:10 /volume1/portainer/Plex/media/Movies
sudo chown -R 1000:10 /volume1/portainer/Plex/media/TvShows
sudo chown -R 1000:10 /volume1/portainer/torrent/download

# Grant full read, write, and execute permissions to the owner group
sudo chmod -R g+rwx /volume1/portainer/Plex/media/Movies
sudo chmod -R g+rwx /volume1/portainer/Plex/media/TvShows
sudo chmod -R g+rwx /volume1/portainer/torrent/download

Step 3: Configure Environment Variables

Create a file named .env in the same directory as your docker-compose.yml and populate it with your specific system values:

# ==============================================================================
# Docker Compose Environment Variables
# ==============================================================================

# Plex Claim Token (Obtain from https://www.plex.tv/claim)
PLEX_CLAIM=claim-xxxxxxxxxxxxxxxxx

# Static IP for Plex on your local macvlan subnet
PLEX_IP=192.168.4.125

# Base path for container configs & databases (Ideally SSD)
DOCKER_CONFIG_DIR=/volume2/SSD/docker

# Common data root directory for media & downloads (Enables hardlinks/instant moves)
DATA_ROOT=/volume1/portainer

# ==============================================================================
# NordVPN & Gluetun VPN Configuration
# ==============================================================================
# Retrieve manual service credentials from your NordVPN dashboard
VPN_SERVICE_PROVIDER=nordvpn
VPN_TYPE=openvpn
OPENVPN_USER=YOUR_NORDVPN_SERVICE_USERNAME
OPENVPN_PASSWORD=YOUR_NORDVPN_SERVICE_PASSWORD
# To use Wireguard instead, set VPN_TYPE=wireguard and fill below:
WIREGUARD_PRIVATE_KEY=
# Specify target country/server (e.g. Netherlands, United Kingdom)
SERVER_COUNTRIES=Netherlands

Step 4: Deploy the Stack

Once your .env is updated and directories are prepared, boot the containers in the background using Docker Compose:

# Start the stack
docker compose up -d

Step 5: Crucial Post-Deployment App Configuration

This stack uses a hybrid approach (local storage + debrid symlinks). To support both, configure your applications as follows:

1. Configure Download Clients in Radarr/Sonarr

In Radarr/Sonarr > Settings > Download Clients:

  • Local Downloader (qBittorrent):
    • Add a qBittorrent client.
    • Set Host to gluetun (since qBittorrent runs inside Gluetun's network namespace).
    • Set Port to 8080.
    • Assign the Tag local.
  • Debrid Downloader (Decypharr):
    • Add a qBittorrent client.
    • Set Host to decypharr.
    • Set Port to 8282.
    • Assign the Tag debrid.

2. Set Up Dual Root Folders in Radarr/Sonarr

Add two distinct root library directories to choose from:

  • Local Path: /data/Plex/media/Movies (or /TvShows) β€” for media you want to store and seed locally.
  • Debrid Path: /mnt/symlinks/Movies (or /TvShows) β€” for media you want to stream via Debrid symlinks.

3. Tag Media for Routing

When monitoring or adding media in Radarr/Sonarr, assign the tag debrid to route the torrent to Decypharr (cloud streaming), or the tag local to route it to qBittorrent (local storage and seeding).

4. Configure Plex Library Sources

In your Plex Library settings, point your libraries to both local and debrid folders to merge them:

  • Movies Library: Add /data/Plex/media/Movies AND /mnt/symlinks/Movies.
  • TV Shows Library: Add /data/Plex/media/TvShows AND /mnt/symlinks/TvShows.

πŸ”Œ Service Port Registry

Once deployed, the services will be accessible at the following local addresses:

Service Address / URL Internal Port Description
Plex http://192.168.4.125:32400/web 32400 Media Server Web Portal
Decypharr http://<DOCKER_HOST_IP>:8282 8282 Blackhole & Cache Interface
qBittorrent http://<DOCKER_HOST_IP>:8080 8080 Local Torrent Client (VPN Routed)
Radarr http://<DOCKER_HOST_IP>:7878 7878 Movies Management
Sonarr http://<DOCKER_HOST_IP>:8989 8989 TV Show/Series Management
Plusarr (Pulsarr) http://<DOCKER_HOST_IP>:3003 3003 Torrent Search/Proxy
Prowlarr http://<DOCKER_HOST_IP>:9696 9696 Indexer Management
Flaresolverr http://<DOCKER_HOST_IP>:8191 8191 Cloudflare Bypass Proxy

πŸ” Troubleshooting Permissions

Tip

If you encounter issues where Plex or Arr applications don't have read/write access to media folders (resulting in "Permission Denied" errors), run this check on the host system:

ls -ltr /volume1/portainer/Plex/media/

Check which user and group owns the target folders. The PUID and PGID in docker-compose.yml (default 1000 / 10) must align with the owner of the files on the host system.

About

A premium, VPN-secured Docker Compose media stack using a hybrid local storage and Real-Debrid symlink workflow (Plex, qBittorrent, Gluetun, Decypharr, and the Arr Suite).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors