SkillAgentSearch skills...

media

Media Management (\*arr Stack) Skill

Install / Use

npx skills add olafkfreund/nixos_config

Installs into whichever agent you are using.

About this skill

Gemini Rules

Gemini CLI config

Quality Score

73/100

Supported Platforms

Gemini CLI

Tags


name: media version: 1.0 description: Media Management (*arr Stack) Skill

Media Management (*arr Stack) Skill

Overview

The *arr stack (Radarr, Sonarr, Lidarr, Prowlarr, and related applications) is a comprehensive suite of media automation tools for managing, downloading, and organizing movies, TV shows, music, and other media content. These applications work together to provide automated media acquisition, organization, and integration with media servers like Plex and Jellyfin.

Key Applications

  • Radarr: Movie collection manager and downloader
  • Sonarr: TV series collection manager and downloader
  • Lidarr: Music collection manager and downloader
  • Prowlarr: Indexer manager that integrates with all *arr applications
  • Jackett: Legacy indexer proxy (being replaced by Prowlarr)

Key Features

  • Automated media acquisition: Monitor releases and automatically download when available
  • Quality management: Define quality profiles and upgrade media automatically
  • Metadata management: Fetch and organize metadata, artwork, and subtitles
  • Indexer integration: Connect to multiple indexers through Prowlarr
  • Download client support: Integrate with NZBGet, Transmission, qBittorrent, and more
  • Media server integration: Direct integration with Plex, Jellyfin, and Emby
  • Calendar tracking: Track release schedules and upcoming content
  • Rename and organize: Automatically rename and organize files with customizable patterns
  • API access: Full REST API for automation and custom integrations

Why Use the *arr Stack?

Problem: Managing a media library manually is time-consuming and error-prone:

  • Manually searching for new releases across multiple sites
  • Inconsistent file naming and organization
  • Missing metadata and artwork
  • No automated quality upgrades
  • Complex integration between download clients and media servers
  • Difficult to track what's been downloaded vs. what's wanted

Solution: The *arr stack provides a unified, automated solution that:

  • Monitors multiple indexers automatically through Prowlarr
  • Downloads content based on your quality preferences
  • Organizes and renames files consistently
  • Integrates seamlessly with media servers
  • Upgrades content when better quality becomes available
  • Provides a modern web interface for management

How It Works

graph TD
    User[User Request] --> Arr[*arr Application]
    Arr --> Prowlarr
    Prowlarr --> Indexers
    Arr --> Client[Download Client NZBGet/Transmission]
    Client --> Media[Downloaded Media]
    Media --> Server[Media Server Plex/Jellyfin]
  1. Add Content: Add movies (Radarr), TV shows (Sonarr), or music (Lidarr) to your library
  2. Search Indexers: Prowlarr queries configured indexers for available releases
  3. Quality Matching: *arr apps filter results based on quality profiles and preferences
  4. Download: Send best match to download client (NZBGet, Transmission, etc.)
  5. Post-Processing: Rename, organize, and move completed downloads
  6. Metadata: Fetch and organize metadata, artwork, and subtitles
  7. Media Server: Notify media server (Plex, Jellyfin) of new content
  8. Monitoring: Continue monitoring for quality upgrades

Project Information

  • Servarr Organization: https://servarr.com
  • Servarr Wiki: https://wiki.servarr.com
  • License: GPL-3.0
  • Platforms: Windows, Linux, macOS, Docker
  • NixOS: Native service modules available
  • Maturity: Production-ready, widely used in home media setups

Installation on NixOS

NixOS with Flakes (Recommended)

The standard NixOS packages include native service modules for all *arr applications:

# configuration.nix or flake module
{ config, pkgs, ... }:
{
  services = {
    # Indexer manager (core component)
    prowlarr = {
      enable = true;
      openFirewall = true;  # Opens port 9696
    };

    # Movie manager
    radarr = {
      enable = true;
      openFirewall = true;  # Opens port 7878
    };

    # TV series manager
    sonarr = {
      enable = true;
      openFirewall = true;  # Opens port 8989
    };

    # Music manager
    lidarr = {
      enable = true;
      openFirewall = true;  # Opens port 8686
    };

    # Legacy indexer proxy (optional)
    jackett = {
      enable = true;
      openFirewall = true;  # Opens port 9117
    };
  };
}

Using Unstable Packages

For the latest versions:

{ config, pkgs, pkgs-unstable, ... }:
{
  services = {
    prowlarr = {
      enable = true;
      package = pkgs-unstable.prowlarr;
    };

    radarr = {
      enable = true;
      package = pkgs-unstable.radarr;
    };

    sonarr = {
      enable = true;
      package = pkgs-unstable.sonarr;
    };

    lidarr = {
      enable = true;
      package = pkgs-unstable.lidarr;
    };
  };
}

Alternative: Nixarr Module

The Nixarr module provides a comprehensive media server stack with built-in VPN support:

Add to your flake.nix:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixarr.url = "github:rasmus-kirk/nixarr";
  };

  outputs = { nixpkgs, nixarr, ... }: {
    nixosConfigurations.mediaserver = nixpkgs.lib.nixosSystem {
      modules = [
        nixarr.nixosModules.default
        ./configuration.nix
      ];
    };
  };
}

Use in configuration:

{ config, ... }:
{
  nixarr = {
    enable = true;

    # VPN support
    vpn = {
      enable = true;
      wgConf = "/path/to/wireguard.conf";
    };

    # Media apps
    radarr.enable = true;
    sonarr.enable = true;
    lidarr.enable = true;
    prowlarr.enable = true;

    # Media servers
    jellyfin.enable = true;
    plex.enable = true;

    # Download clients
    transmission.enable = true;
  };
}

NixOS Service Configuration Reference

Common Options (All *arr Services)

All *arr applications share these common NixOS service options:

enable

Type: boolean Default: false

Enable the service.

services.radarr.enable = true;

package

Type: package Default: Service-specific package from nixpkgs

Package to use for the service.

services.radarr.package = pkgs-unstable.radarr;

dataDir

Type: string Default: /var/lib/<service>

Directory where the service stores its data.

services.radarr.dataDir = "/mnt/media/radarr";

Important: Ensure the directory exists and has correct permissions:

systemd.tmpfiles.rules = [
  "d /mnt/media/radarr 0755 <user> <group> -"
];

openFirewall

Type: boolean Default: false

Automatically open the firewall port for the service.

services.prowlarr.openFirewall = true;

Alternatively, manually configure firewall:

networking.firewall.allowedTCPPorts = [
  7878  # Radarr
  8989  # Sonarr
  8686  # Lidarr
  9696  # Prowlarr
];

user

Type: string Default: Service-specific user

User account under which the service runs.

services.radarr.user = "media";

group

Type: string Default: Service-specific group

Group under which the service runs.

services.radarr.group = "media";

Service-Specific Ports

Default ports for each service:

  • Radarr: 7878
  • Sonarr: 8989
  • Lidarr: 8686
  • Prowlarr: 9696
  • Jackett: 9117
  • Readarr: 8787

Radarr Configuration

{ config, pkgs, ... }:
{
  services.radarr = {
    enable = true;
    dataDir = "/mnt/media/radarr";
    package = pkgs.radarr;
    user = "media";
    group = "media";
    openFirewall = true;
  };

  # Ensure data directory exists
  systemd.tmpfiles.rules = [
    "d /mnt/media/radarr 0755 media media -"
  ];
}

Sonarr Configuration

{ config, pkgs, ... }:
{
  services.sonarr = {
    enable = true;
    dataDir = "/mnt/media/sonarr";
    package = pkgs.sonarr;
    user = "media";
    group = "media";
    openFirewall = true;
  };

  systemd.tmpfiles.rules = [
    "d /mnt/media/sonarr 0755 media media -"
  ];
}

Lidarr Configuration

{ config, pkgs, ... }:
{
  services.lidarr = {
    enable = true;
    dataDir = "/mnt/media/lidarr";
    package = pkgs.lidarr;
    user = "media";
    group = "media";
    openFirewall = true;
  };

  systemd.tmpfiles.rules = [
    "d /mnt/media/lidarr 0755 media media -"
  ];
}

Prowlarr Configuration

{ config, pkgs, ... }:
{
  services.prowlarr = {
    enable = true;
    dataDir = "/mnt/media/prowlarr";
    package = pkgs.prowlarr;
    openFirewall = true;
  };

  systemd.tmpfiles.rules = [
    "d /mnt/media/prowlarr 0755 prowlarr prowlarr -"
  ];
}

Complete Media Server Configuration Example

Here's a comprehensive configuration for a complete media server:

{ config, pkgs, pkgs-unstable, ... }:
{
  # Create a shared media user
  users.users.media = {
    isSystemUser = true;
    group = "media";
    extraGroups = [ "transmission" "nzbget" ];
  };

  users.groups.media = {};

  services = {
    # Indexer manager
    prowlarr = {
      enable = true;
      dataDir = "/mnt/media/prowlarr";
      package = pkgs-unstable.prowlarr;
      openFirewall = true;
    };

    # Movie manager
    radarr = {
      enable = true;
      user = "media";
      dataDir = "/mnt/media/radarr";
      package = pkgs-unstable.radarr;
      openFirewall = true;
    };

    # TV series manager
    sonarr = {
      enable = true;
      user = "media";
      dataDir = "/mnt/media/sonarr";
      package = pkgs-unstable.sonarr;
      openFirewall = true;
    };

    # Music manager
    lidarr = {
      enable = true;
      user = "media";
      dataDir = "/mnt/media/lidarr";
      package = pkgs-unstable.lidarr;
      openFirewall = true;
    };

    # Download client - NZBGet (Usenet)
    nzbget = {
      enable = true;
      user = "media";
      package = pkgs-unstable.nzbget;
      settings = {
        MainDir = "/mnt/media/nzbget";
        DestDir = "/mnt/media/Media/Downloads";
        InterDir = "/mnt/media/nzbget/intermediate";
        QueueDir = "/mnt/media/nzbget/queue";
        TempDir = "/mnt/media/nzbget/tmp";
        ControlIP = "0.0.0.0";
        ControlPort = 6789;
      };
    };

    # Download client - Transmission (Torrents)
    transmission = {
      enable = true;
      user = "media";
      home = "/mnt/media/transmission";
      package = pkgs-unstable.transmission_4;
      settings = {
        rpc-bind-address = "0.0.0.0";
        rpc-whitelist = "127.0.0.1,192.168.*.*";
        download-dir = "/mnt/media/Media/Downloads";
        incomplete-dir = "/mnt/media/transmission/incomplete";
        incomplete-dir-enabled = true;
      };
    };

    # Media server - Plex
    plex = {
      enable = true;
      user = "media";
      dataDir = "/mnt/media/plex";
      package = pkgs-unstable.plex;
    };
  };

  # Create all required directories
  systemd.tmpfiles.rules = [
    "d /mnt/media/prowlarr 0755 prowlarr prowlarr -"
    "d /mnt/media/radarr 0755 media media -"
    "d /mnt/media/sonarr 0755 media media -"
    "d /mnt/media/lidarr 0755 media media -"
    "d /mnt/media/nzbget 0755 media media -"
    "d /mnt/media/nzbget/intermediate 0755 media media -"
    "d /mnt/media/nzbget/queue 0755 media media -"
    "d /mnt/media/nzbget/tmp 0755 media media -"
    "d /mnt/media/transmission 0755 media media -"
    "d /mnt/media/transmission/incomplete 0755 media media -"
    "d /mnt/media/Media/Downloads 0755 media media -"
    "d /mnt/media/Media/Movies 0755 media media -"
    "d /mnt/media/Media/TV 0755 media media -"
    "d /mnt/media/Media/Music 0755 media media -"
    "d /mnt/media/plex 0755 media media -"
  ];

  # Firewall configuration
  networking.firewall.allowedTCPPorts = [
    6789   # NZBGet
    7878   # Radarr
    8686   # Lidarr
    8989   # Sonarr
    9091   # Transmission
    9696   # Prowlarr
    32400  # Plex
  ];
}

Initial Setup and Con

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars0
CategoryDevelopment
Updated2d ago
Forks0

Security Score

80/100

Audited on Sep 3, 2026

1 medium1 low