---
author: The Bunker Admin
date: 2025 04 29
tags: [sript]
---
## build.mediastack

This script is for getting the mediastack operating on the [[build.homelab]]. Also see: 

- [[config.mediastack]] for configuration instructions

> [!note] Repository
> 
> This entire stack is available as a repository for download. Contact admin@thebunkerops.ca for more information. 

---

I am going to use Docker Compose to do this full deployment. With some tweaking, should be able to get this whole system up and running in a single .yml that can be shared later. 
## Plex 
Plex is installed as a .deb. It can be downloaded from the [Plex website.](https://www.plex.tv/media-server-downloads/?cat=computer&plat=linux#plex-media-server)
#### Plex also requires setup of drive permissions to access data on drives. See the [[config.drives.homelab#Plex Media Permissions]] for more info. 
## Full Docker Compose 
_*Individual services defined below_

> [!info] Drive Setup
> 
> The `volumes` section of the entire docker compose do need to be updated to point to the necessary directories on the users system. 
> 

```
---
services:
  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - WEBUI_PORT=8082
      - TORRENTING_PORT=6881
    volumes:
      - /mnt/storage4tb/mediastack/configs/qbittorrent:/config
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 8082:8082
      - 6881:6881
      - 6881:6881/udp
    restart: unless-stopped
    networks:
      - media

  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    environment:
      - LOG_LEVEL=${LOG_LEVEL:-info}
      - LOG_HTML=${LOG_HTML:-false}
      - CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}
      - TZ=Europe/London
    ports:
      - "${PORT:-8191}:8191"
    restart: unless-stopped
    networks:
      - media

  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/prowlarr:/config
    ports:
      - 9696:9696
    restart: unless-stopped
    networks:
      - media

  radarr:
    image: lscr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/radarr:/config
      - /mnt/storage4tb/mediastack/media/movies:/movies
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 7878:7878
    restart: unless-stopped
    networks:
      - media

  overseerr:
    image: lscr.io/linuxserver/overseerr:latest
    container_name: overseerr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/overseerr:/config
    ports:
      - 5055:5055
    restart: unless-stopped
    networks:
      - media

  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/sonarr:/config
      - /mnt/storage4tb/mediastack/media/tv:/tv
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 8989:8989
    restart: unless-stopped
    networks:
      - media


  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    ports:
      - 3000:3000
    volumes:
      - /mnt/storage4tb/mediastack/configs/homepage:/app/config
      - /mnt/storage4tb/mediastack/configs/homepage/images:/app/public/images
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - HOMEPAGE_ALLOWED_HOSTS=*
    restart: unless-stopped
    networks:
      - media


  tautulli:
    image: ghcr.io/tautulli/tautulli:latest
    container_name: tautulli
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/tautulli:/config
    ports:
      - 8181:8181
    restart: unless-stopped
    networks:
      - media

  whisparr:
    image: ghcr.io/hotio/whisparr:latest
    container_name: whisparr
    environment:
      - PUID=1000
      - PGID=1000
      - UMASK=002
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/whisparr:/config
      - /mnt/storage4tb/mediastack/media/other:/other
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 6969:6969
    restart: unless-stopped
    networks:
      - media

  bazarr:
    image: lscr.io/linuxserver/bazarr:latest
    container_name: bazarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/bazarr:/config
      - /mnt/storage4tb/mediastack/media/movies:/movies
      - /mnt/storage4tb/mediastack/media/tv:/tv
    ports:
      - 6767:6767
    restart: unless-stopped
    networks:
      - media

  decluttarr:
    image: ghcr.io/manimatter/decluttarr:latest
    container_name: decluttarr
    restart: always
    depends_on:
      - radarr
      - sonarr
      - whisparr
    networks:
      - media
    environment:
      TZ: mnt/Canada/Edmonton
      PUID: 1000
      PGID: 1000

      ## General
      # TEST_RUN: True
      # SSL_VERIFICATION: False
      LOG_LEVEL: INFO

      ## Features
      REMOVE_TIMER: 10
      REMOVE_FAILED: True
      REMOVE_FAILED_IMPORTS: True
      REMOVE_METADATA_MISSING: True
      REMOVE_MISSING_FILES: True
      REMOVE_ORPHANS: True
      REMOVE_SLOW: True
      REMOVE_STALLED: True
      REMOVE_UNMONITORED: True
      RUN_PERIODIC_RESCANS: '
        {
        "SONARR": {"MISSING": true, "CUTOFF_UNMET": true, "MAX_CONCURRENT_SCANS": 3, "MIN_DAYS_BEFORE_RESCAN": 7},
        "RADARR": {"MISSING": true, "CUTOFF_UNMET": true, "MAX_CONCURRENT_SCANS": 3, "MIN_DAYS_BEFORE_RESCAN": 7}
        }'

      # Feature Settings
      PERMITTED_ATTEMPTS: 3
      NO_STALLED_REMOVAL_QBIT_TAG: Don't Kill
      MIN_DOWNLOAD_SPEED: 100
      FAILED_IMPORT_MESSAGE_PATTERNS: '
        [
        "Not a Custom Format upgrade for existing",
        "Not an upgrade for existing"
        ]'
      IGNORED_DOWNLOAD_CLIENTS: '
        [
        ]'

      ## Radarr
      RADARR_URL: ${RADARR_URL:-http://radarr:7878}
      RADARR_KEY: ${RADARR_API_KEY}

      ## Sonarr
      SONARR_URL: ${SONARR_URL:-http://sonarr:8989}
      SONARR_KEY: ${SONARR_API_KEY}

      ## Whisparr
      WHISPARR_URL: ${WHISPARR_URL:-http://whisparr:6969}
      WHISPARR_KEY: ${WHISPARR_API_KEY}

      ## qBitorrent
      QBITTORRENT_URL: ${QBITTORRENT_URL:-http://qbittorrent:8080}
      QBITTORRENT_USERNAME: ${QBITTORRENT_USERNAME:-admin}
      QBITTORRENT_PASSWORD: ${QBITTORRENT_PASSWORD:-adminadmin}


networks:
  media:
    driver: bridge
```

## [Qbitorrent](https://hub.docker.com/r/linuxserver/qbittorrent)
Getting started with Qbitorrent 

```
---
services:
  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - WEBUI_PORT=8082
      - TORRENTING_PORT=6881
    volumes:
      - /media/bunker-admin/archive/media/configs/qbittorrent:/config
      - /media/bunker-admin/archive/media/downloads:/downloads
    ports:
      - 8082:8082
      - 6881:6881
      - 6881:6881/udp
    restart: unless-stopped
```

## [Flaresoverr](https://github.com/FlareSolverr/FlareSolverr)
Flaresoverr helps Prowlarr with cloudflare challenges. 

```
---
services: 
  flaresolverr:
    # DockerHub mirror flaresolverr/flaresolverr:latest
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    environment:
      - LOG_LEVEL=${LOG_LEVEL:-info}
      - LOG_HTML=${LOG_HTML:-false}
      - CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}
      - TZ=Europe/London
    ports:
      - "${PORT:-8191}:8191"
    restart: unless-stopped
```
## [Prowlarr](https://hub.docker.com/r/linuxserver/prowlarr)
Handles the indexers (torrent backend). 

```
---
services: 
  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /media/bunker-admin/archive/media/configs/prowlarr:/config
    ports:
      - 9696:9696
    restart: unless-stopped
```
## [Radarr](https://hub.docker.com/r/linuxserver/radarr)
Requests and handles media files for movies. 

```
---
services: 
  radarr:
    image: lscr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /media/bunker-admin/archive/media/configs/radarr:/config
      - /media/bunker-admin/archive/media/movies:/movies
      - /media/bunker-admin/archive/media/downloads:/downloads
    ports:
      - 7878:7878
    restart: unless-stopped
```
## [Overseerr](https://hub.docker.com/r/linuxserver/overseerr)
Web-based user interface for requesting and managing media.

```yaml
---
services:
  overseerr:
    image: lscr.io/linuxserver/overseerr:latest
    container_name: overseerr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/overseerr:/config
    ports:
      - 5055:5055
    restart: unless-stopped
    networks:
      - media
```
## [Sonarr](https://hub.docker.com/r/linuxserver/sonarr)
Requests and handles media files for TV shows.

```yaml
---
services:
  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/sonarr:/config
      - /mnt/storage4tb/mediastack/media/tv:/tv
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 8989:8989
    restart: unless-stopped
    networks:
      - media
```

## [Homepage](https://github.com/gethomepage/homepage)
A modern dashboard for all your services and monitoring.

```yaml
---
services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    ports:
      - 3000:3000
    volumes:
      - /mnt/storage4tb/mediastack/configs/homepage:/app/config
      - /mnt/storage4tb/mediastack/configs/homepage/images:/app/public/images
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - HOMEPAGE_ALLOWED_HOSTS=*
    restart: unless-stopped
    networks:
      - media
```

## [Tautulli](https://github.com/Tautulli/Tautulli)
Monitors and tracks Plex Media Server usage statistics.

```yaml
---
services:
  tautulli:
    image: ghcr.io/tautulli/tautulli:latest
    container_name: tautulli
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/tautulli:/config
    ports:
      - 8181:8181
    restart: unless-stopped
    networks:
      - media
```

## [Whisparr](https://github.com/whisparr/whisparr)
Manages adult content media files.

```yaml
---
services:
  whisparr:
    image: ghcr.io/hotio/whisparr:latest
    container_name: whisparr
    environment:
      - PUID=1000
      - PGID=1000
      - UMASK=002
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/whisparr:/config
      - /mnt/storage4tb/mediastack/media/other:/other
      - /mnt/storage4tb/mediastack/media/downloads:/downloads
    ports:
      - 6969:6969
    restart: unless-stopped
    networks:
      - media
```

## [Bazarr](https://hub.docker.com/r/linuxserver/bazarr)
Manages and downloads subtitles for media files.

```yaml
---
services:
  bazarr:
    image: lscr.io/linuxserver/bazarr:latest
    container_name: bazarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /mnt/storage4tb/mediastack/configs/bazarr:/config
      - /mnt/storage4tb/mediastack/media/movies:/movies
      - /mnt/storage4tb/mediastack/media/tv:/tv
    ports:
      - 6767:6767
    restart: unless-stopped
    networks:
      - media
```

## [Decluttarr](https://github.com/manimatter/decluttarr)
Manages and cleans up download clients and *arr applications.

```yaml
---
services:
  decluttarr:
    image: ghcr.io/manimatter/decluttarr:latest
    container_name: decluttarr
    restart: always
    depends_on:
      - radarr
      - sonarr
      - whisparr
    networks:
      - media
    environment:
      TZ: mnt/Canada/Edmonton
      PUID: 1000
      PGID: 1000

      ## General
      # TEST_RUN: True
      # SSL_VERIFICATION: False
      LOG_LEVEL: INFO

      ## Features
      REMOVE_TIMER: 10
      REMOVE_FAILED: True
      REMOVE_FAILED_IMPORTS: True
      REMOVE_METADATA_MISSING: True
      REMOVE_MISSING_FILES: True
      REMOVE_ORPHANS: True
      REMOVE_SLOW: True
      REMOVE_STALLED: True
      REMOVE_UNMONITORED: True
      RUN_PERIODIC_RESCANS: '
        {
        "SONARR": {"MISSING": true, "CUTOFF_UNMET": true, "MAX_CONCURRENT_SCANS": 3, "MIN_DAYS_BEFORE_RESCAN": 7},
        "RADARR": {"MISSING": true, "CUTOFF_UNMET": true, "MAX_CONCURRENT_SCANS": 3, "MIN_DAYS_BEFORE_RESCAN": 7}
        }'

      # Feature Settings
      PERMITTED_ATTEMPTS: 3
      NO_STALLED_REMOVAL_QBIT_TAG: Don't Kill
      MIN_DOWNLOAD_SPEED: 100
      FAILED_IMPORT_MESSAGE_PATTERNS: '
        [
        "Not a Custom Format upgrade for existing",
        "Not an upgrade for existing"
        ]'
      IGNORED_DOWNLOAD_CLIENTS: '
        [
        ]'

      ## Radarr
      RADARR_URL: ${RADARR_URL:-http://radarr:7878}
      RADARR_KEY: ${RADARR_API_KEY}

      ## Sonarr
      SONARR_URL: ${SONARR_URL:-http://sonarr:8989}
      SONARR_KEY: ${SONARR_API_KEY}

      ## Whisparr
      WHISPARR_URL: ${WHISPARR_URL:-http://whisparr:6969}
      WHISPARR_KEY: ${WHISPARR_API_KEY}

      ## qBitorrent
      QBITTORRENT_URL: ${QBITTORRENT_URL:-http://qbittorrent:8080}
      QBITTORRENT_USERNAME: ${QBITTORRENT_USERNAME:-admin}
      QBITTORRENT_PASSWORD: ${QBITTORRENT_PASSWORD:-adminadmin}
```

## Network Configuration
The Docker Compose file creates a dedicated bridge network for all media services to communicate with each other.

```yaml
networks:
  media:
    driver: bridge
```

## Setup Notes

1. Before running the Docker Compose file, ensure all necessary directories exist.
2. You'll need to set environment variables or update the Docker Compose file with API keys for services.
3. For Plex, which is installed as a .deb rather than as a container, ensure proper drive permissions as mentioned in the configuration notes.
4. Adjust all volume paths to match your system's directory structure.
5. Consider security implications when exposing ports to the internet.