Media Server, Pt 7 - Arr stack

The various *arr applications are what I use to acquire media files. Setting them up is not all that complicated; you will need to set up storage space for each of them:

$ mkdir -p /srv/data/docker/{rad,son,read,lid,prowl}arr/{config,custom-cont-init.d,custom-services.d}
$ sudo chgrp -R 10002 /srv/data/docker/{rad,son,read,lid,prowl}arr
$ sudo chown -R 10009 /srv/data/docker/prowlarr
$ sudo chown -R 10010 /srv/data/docker/lidarr
$ sudo chown -R 10013 /srv/data/docker/sonarr
$ sudo chwon -R 10014 /srv/dara/docker/radarr
$ sudo chown -R 10017 /srv/data/docker/readarr
$ sudo chgrp -R g-rwx,o-rwx /srv/data/docker/{rad,son,read,lid,prowl}arr

The relevant compose file snippets are

  lidarr:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.lidarr-rtr.entrypoints: "websecure"
        traefik.http.routers.lidarr-rtr.middlewares: "authentik@swarm"
        traefik.http.routers.lidarr-rtr.rule: "Host(`lidarr.your.domain`)"
        traefik.http.routers.lidarr-rtr.service: "lidarr"
        traefik.http.services.lidarr.loadbalancer.server.port: "8686"
      replicas: 1
    environment:
      PUID: 10010
      PGID: 10002
      UMASK: 0002
      TZ: "Etc/UTC"
    healthcheck:
      test: "curl -f http://localhost:8686"
      interval: 2m
      timeout: 5s
      start_period: 20s
    hostname: "lidarr"
    image: "linuxserver/lidarr"
    networks:
      - homelab
    restart: on-failure
    volumes:
      - "/srv/data/docker/lidarr/config:/config"
      - "/srv/data/shared/deemix:/data/deemix"
      - "/srv/data/shared/usenet:/data/usenet"
      - "/srv/data/shared/torrent:/data/torrent"
      - "/srv/data/shared/media:/data/media"
      - "/srv/data/docker/lidarr/custom-services.d:/custom-services.d"
      - "/srv/data/docker/lidarr/custom-cont-init.d:/custom-cont-init.d"
  prowlarr:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.prowlarr-rtr.entrypoints: "websecure"
        traefik.http.routers.prowlarr-rtr.middlewares: "authentik@swarm"
        traefik.http.routers.prowlarr-rtr.rule: "Host(`prowlarr.your.domain`)"
        traefik.http.routers.prowlarr-rtr.service: "prowlarr"
        traefik.http.services.prowlarr.loadbalancer.server.port: "9696"
        replicas: 1
    environment:
      PUID: 10009
      PGID: 10009
      UMASK: 0002 
      TZ: "Etc/UTC"
    healthcheck:
      test: "curl -f http://localhost:9696"
      interval: 2m
      timeout: 5s
      start_period: 20s
    hostname: "prowlarr"
    image: "linuxserver/prowlarr:latest"
    networks:
      - homelab
    restart: on-failure
    volumes:
      - "/srv/data/docker/prowlarr/config:/config"
  radarr:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.radarr-rtr.entrypoints: "websecure"
        traefik.http.routers.radarr-rtr.middlewares: "authentik@swarm"
        traefik.http.routers.radarr-rtr.rule: "Host(`radarr.your.domain`)"
        traefik.http.routers.radarr-rtr.service: "radarr"
        traefik.http.services.radarr.loadbalancer.server.port: "7878"
      replicas: 1
    environment:
      PUID: 10014
      PGID: 10002
      UMASK: 0002
      TZ: "Etc/UTC"
    healthcheck:
      test: "curl -f http://localhost:7878"
      interval: 2m
      timeout: 5s
      start_period: 20s
    hostname: "radarr"
    image: "linuxserver/radarr:latest"
    networks:
      - homelab
    restart: on-failure
    volumes:
      - "/srv/data/docker/radarr/config:/config"
      - "/srv/data/shared/usenet:/data/usenet"
      - "/srv/data/shared/torrent:/data/torrent"
      - "/srv/data/shared/media:/data/media"
      - "/srv/data/docker/radarr/custom-cont-init.d:/custom-cont-init.d"
      - "/srv/data/docker/radarr/custom-services.d:/custom-services.d"
  readarr:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.readarr-rtr.entrypoints: "websecure"
        traefik.http.routers.readarr-rtr.middlewares: "authentik@swarm"
        traefik.http.routers.readarr-rtr.rule: "Host(`readarr.your.domain`)"
        traefik.http.routers.readarr-rtr.service: "readarr"
        traefik.http.services.readarr.loadbalancer.server.port: "8787"
      replicas: 1
    environment:
      PUID: 10017
      PGID: 10002
      UMASK: 0002
      TZ: "Etc/UTC"
    healthcheck:
      test: "curl -f http://localhost:8787"
      interval: 2m
      timeout: 5s
      start_period: 20s
    hostname: "readarr"
    image: "linuxserver/readarr:develop"
    networks:
      - homelab
    restart: on-failure
    volumes:
      - "/srv/data/docker/readarr/config:/config"
      - "/srv/data/shared/usenet:/data/usenet"
      - "/srv/data/shared/torrent:/data/torrent"
      - "/srv/data/shared/media:/data/media"
      - "/srv/data/docker/readarr/custom-cont-init.d:/custom-cont-init.d"
      - "/srv/data/docker/readarr/custom-services.d:/custom-services.d"
  sonarr:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.sonarr-rtr.entrypoints: "websecure"
        traefik.http.routers.sonarr-rtr.middlewares: "authentik@swarm"
        traefik.http.routers.sonarr-rtr.rule: "Host(`sonarr.your.domain`)"
        traefik.http.routers.sonarr-rtr.service: "sonarr"
        traefik.http.services.sonarr.loadbalancer.server.port: "8989"
      replicas: 1
    environment:
      PUID: 10013
      PGID: 10002
      UMASK: 0002
      TZ: "Etc/UTC"
    healthcheck:
      test: "curl -f http://localhost:8989"
      interval: 2m
      timeout: 5s
      start_period: 20s
    hostname: "sonarr"
    image: "linuxserver/sonarr:latest"
    networks:
      - homelab
    restart: on-failure
    volumes:
      - "/srv/data/docker/sonarr/config:/config"
      - "/srv/data/shared/usenet:/data/usenet"
      - "/srv/data/shared/torrent:/data/torrent"
      - "/srv/data/shared/media:/data/media"
      - "/srv/data/docker/radarr/custom-cont-init.d:/custom-cont-init.d"
      - "/srv/data/docker/radarr/custom-services.d:/custom-services.d"

You'll need to set up forward authentication for each of those servers. To do so, open your Authentik server's web UI, go to Admin Interface > Applications > Providers and set up providers for each of your Arr applications. They all look the same; use the default authentication flow, explicit consent authorization flow, set them to forward authentication tbe external host as https://<application>.<your domain>. Under Advanced Protocol Settings, you'll want to add two lines to Unauthenticated Paths: "^/api" and "^/api/.*" Those are not actually unauthenticated, they require an API key to use, but we don't want Authentik to get into machine-to-machine authentication.

Go to Applications > Application and set up the applications for each of those containers, then add them to the internal outpost, so they actually get used.

Then update your stack.

$ docker stack deploy -c <compose file> --prune homelab

Then update your stack.

$ docker stack deploy -c <compose file> --prune homelab

At this point, you'll want to collect a few API keys you will need from assorted configuration files. Specifically, you'll need API keys for the Arr stack, sabnzbd and Transmission. Get them by running:

$ sudo grep -i api /srv/data/docker/*arr/config/config.xml /srv/data/docker/sabnzbd/config/sabnzbd.ini

You'll notice we're not grabbing an API key from Transmission. This is by design - Transmission's API is wide open, and we simply don't expose it unauthenticated to the outside world. For internal communication, we'll bypass the authentication proxy.

Now, open the web UI for Prowlarr and navigate to Settings > Apps. You'll want to configure each of your Arr services here, with it's respective API key, to distribute indexer settings. Then head to Settings > Download Clients and configure Sabnzbd and Transmission as download clients for Prowlarr. Finally, go to Indexers and configure those. This is where I'm going to be cagey. The subreddit r/usenet has more information, and I encourage you to pay those good folks a visit. Similarly, visit r/torrent for information on torrent trackers.

Finally, visit Lidarr, Radarr, Readarr and Sonarr and set up your download clients in those applications as well. You'll need to set up a root folder in Settings > Media Management. We set those up earlier - point the root folder to /srv/data/media/<media type> for each of the four *Arrs. You can import existing libraries by making them available to the Docker container (add a line like '-"/<your exisiting library>:/data/media/import:ro"' to your compose file for the relevant application and go to Wanted > Manual Import to pull your library in. You will want to select Hardlink/Copy Files as import method, as you likely don't want to move those files and lose your original library until you're certain the import worked.

Subscribe to Homelab Adventures

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe