### Complete Nixflix Production Example Source: https://context7.com/kiriwalawren/nixflix/llms.txt A comprehensive Nix configuration for a production environment, enabling and configuring various services including media servers, Usenet clients, and reverse proxies. ```nix { config, lib, ... }: { sops.secrets = { "sonarr/api_key" = {}; "sonarr/password" = {}; "radarr/api_key" = {}; "radarr/password" = {}; "prowlarr/api_key" = {}; "prowlarr/password" = {}; "indexers/nzbgeek" = {}; "sabnzbd/api_key" = {}; "sabnzbd/nzb_key" = {}; "usenet/eweka/username" = {}; "usenet/eweka/password" = {}; "jellyfin/api_key" = {}; "jellyfin/admin_pw" = {}; "seerr/api_key" = {}; "wireguard/conf" = {}; }; nixflix = { enable = true; mediaDir = "/data/media"; stateDir = "/data/.state"; mediaUsers = [ "alice" ]; theme = { enable = true; name = "overseerr"; }; nginx = { enable = true; addHostsEntries = true; }; postgres.enable = true; vpn = { enable = true; wgConfFile = config.sops.secrets."wireguard/conf".path; accessibleFrom = [ "192.168.1.0/24" ]; }; sonarr = { enable = true; vpn.enable = true; config.apiKey._secret = config.sops.secrets."sonarr/api_key".path; config.hostConfig.password._secret = config.sops.secrets."sonarr/password".path; }; radarr = { enable = true; vpn.enable = true; config.apiKey._secret = config.sops.secrets."radarr/api_key".path; config.hostConfig.password._secret = config.sops.secrets."radarr/password".path; }; prowlarr = { enable = true; config = { apiKey._secret = config.sops.secrets."prowlarr/api_key".path; hostConfig.password._secret = config.sops.secrets."prowlarr/password".path; indexers = [ { name = "NZBGeek"; apiKey._secret = config.sops.secrets."indexers/nzbgeek".path; } ]; }; }; usenetClients.sabnzbd = { enable = true; vpn.enable = true; settings = { misc = { api_key._secret = config.sops.secrets."sabnzbd/api_key".path; nzb_key._secret = config.sops.secrets."sabnzbd/nzb_key".path; }; servers = [{ name = "Eweka"; host = "sslreader.eweka.nl"; port = 563; username._secret = config.sops.secrets."usenet/eweka/username".path; password._secret = config.sops.secrets."usenet/eweka/password".path; connections = 20; ssl = true; priority = 0; }]; }; }; jellyfin = { enable = true; apiKey._secret = config.sops.secrets."jellyfin/api_key".path; users.admin = { mutable = false; password._secret = config.sops.secrets."jellyfin/admin_pw".path; policy.isAdministrator = true; }; }; seerr = { enable = true; apiKey._secret = config.sops.secrets."seerr/api_key".path; }; recyclarr = { enable = true; cleanupUnmanagedProfiles.enable = true; }; }; } ``` -------------------------------- ### Basic Jellyfin Media Server Setup Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enable Jellyfin and configure API key access. Define user roles, including administrators with full permissions and guest users with restricted access and login attempt limits. This is essential for setting up a functional media server. ```nix { config, pkgs, ... }: { nixflix.jellyfin = { enable = true; apiKey._secret = config.sops.secrets."jellyfin/api_key".path; # At least one user must be an administrator users = { admin = { mutable = false; # false = nix config always wins over GUI changes password._secret = config.sops.secrets."jellyfin/admin_password".path; policy = { isAdministrator = true; enableMediaPlayback = true; enableContentDeletion = true; maxActiveSessions = 0; # 0 = unlimited }; configuration = { subtitleMode = "Smart"; enableNextEpisodeAutoPlay = true; audioLanguagePreference = "eng"; subtitleLanguagePreference = "eng"; }; }; guest = { mutable = true; policy = { isAdministrator = false; enableContentDeletion = false; maxActiveSessions = 2; loginAttemptsBeforeLockout = 5; accessSchedules = [ { dayOfWeek = "Everyday"; startHour = 8; endHour = 22; } ]; }; }; }; }; } ``` -------------------------------- ### Configure qBittorrent Torrent Client Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enable qBittorrent and configure its web UI port, integration password, VPN routing, and custom download categories with isolated save paths. This setup is useful for managing downloads across different media services. ```nix { config, pkgs, ... }: { nixflix.torrentClients.qbittorrent = { enable = true; webuiPort = 8282; # Integration password (so Arr services can authenticate) password._secret = config.sops.secrets."qbittorrent/password".path; # Route through VPN (defaults to nixflix.vpn.enable) vpn.enable = true; # Override category save paths (auto-generated from enabled services by default) categories = { radarr = "/data/downloads/torrent/radarr"; sonarr = "/data/downloads/torrent/sonarr"; "sonarr-anime" = "/data/downloads/torrent/sonarr-anime"; lidarr = "/data/downloads/torrent/lidarr"; }; # qBittorrent serverConfig options (maps to services.qbittorrent.serverConfig) serverConfig = { BitTorrent.Session = { DefaultSavePath = "/data/downloads/torrent/default"; DisableAutoTMMByDefault = false; # false = Automatic mode (use category paths) }; Preferences.WebUI.Password_PBKDF2 = "..."; # set hashed password directly }; }; } ``` -------------------------------- ### Add New NixOS VM Test Source: https://github.com/kiriwalawren/nixflix/blob/main/tests/README.md Example of how to define a new VM test in Nix. It sets up a NixOS configuration for a node and defines a test script to run against it. ```nix { system ? builtins.currentSystem, pkgs ? import {inherit system;}, nixosModules, }: pkgs.testers.runNixOSTest { name = "my-test"; nodes.machine = {config, pkgs, ...}: { imports = [nixosModules]; services.nixflix = { enable = true; user = "testuser"; # ... your configuration }; users.users.testuser = { isNormalUser = true; createHome = true; }; }; testScript = '' start_all() machine.wait_for_unit("sonarr.service") # ... your test assertions ''; } ``` -------------------------------- ### Minimal Nixflix Configuration Example Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md A basic Nixflix configuration enabling essential services like reverse proxy, PostgreSQL, Sonarr, Radarr, Prowlarr, SABnzbd, and Jellyfin. Secrets are managed via sops-nix. ```nix { ... }: { nixflix = { enable = true; mediaDir = "/data/media"; stateDir = "/data/.state"; # Reverse proxy: choose one nginx.enable = true; # caddy.enable = true; postgres.enable = true; sonarr = { enable = true; config = { apiKey = {_secret = config.sops.secrets."sonarr/api_key".path;}; hostConfig.password = {_secret = config.sops.secrets."sonarr/password".path;}; }; }; radarr = { enable = true; config = { apiKey = {_secret = config.sops.secrets."radarr/api_key".path;}; hostConfig.password = {_secret = config.sops.secrets."radarr/password".path;}; }; }; prowlarr = { enable = true; config = { apiKey = {_secret = config.sops.secrets."prowlarr/api_key".path;}; hostConfig.password = {_secret = config.sops.secrets."prowlarr/password".path;}; }; }; sabnzbd = { enable = true; settings = { misc.api_key = {_secret = config.sops.secrets."sabnzbd/api_key".path;}; }; }; jellyfin = { enable = true; users.admin = { policy.isAdministrator = true; password = {_secret = config.sops.secrets."jellyfin/admin_password".path;}; }; }; }; } ``` -------------------------------- ### Nix Media Server Configuration Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/basic-setup.md This Nix configuration defines a complete media server setup. It includes enabling and configuring services such as Sonarr, Radarr, Lidarr, Prowlarr, SABnzbd, Jellyfin, Seerr, and a WireGuard VPN. Secrets for API keys, passwords, and user credentials are managed using SOPS. It also configures reverse proxy options (Nginx or Caddy) and a PostgreSQL database. ```nix { config, pkgs, ... }: { sops.secrets = { "sonarr/api_key" = {}; "sonarr/password" = {}; "radarr/api_key" = {}; "radarr/password" = {}; "lidarr/api_key" = {}; "lidarr/password" = {}; "prowlarr/api_key" = {}; "prowlarr/password" = {}; "indexer-api-keys/DrunkenSlug" = {}; "indexer-api-keys/NZBFinder" = {}; "indexer-api-keys/NzbPlanet" = {}; "jellyfin/alice_password" = {}; "seerr/api_key" = {}; "wireguard/conf" = {}; "sabnzbd/api_key" = {}; "sabnzbd/nzb_key" = {}; "usenet/eweka/username" = {}; "usenet/eweka/password" = {}; "usenet/newsgroupdirect/username" = {}; "usenet/newsgroupdirect/password" = {}; }; nixflix = { enable = true; mediaDir = "/data/media"; stateDir = "/data/.state"; mediaUsers = ["myuser"]; theme = { enable = true; name = "overseerr"; }; # Reverse proxy (choose nginx or caddy, not both) nginx = { enable = true; addHostsEntries = true; # Disable this if you have your own DNS configuration }; # caddy = { # enable = true; # addHostsEntries = true; # }; postgres.enable = true; sonarr = { enable = true; config = { apiKey._secret = config.sops.secrets."sonarr/api_key".path; hostConfig.password._secret = config.sops.secrets."sonarr/password".path; }; }; radarr = { enable = true; config = { apiKey._secret = config.sops.secrets."radarr/api_key".path; hostConfig.password._secret = config.sops.secrets."radarr/password".path; }; }; recyclarr = { enable = true; cleanupUnmanagedProfiles = true; }; lidarr = { enable = true; config = { apiKey._secret = config.sops.secrets."lidarr/api_key".path; hostConfig.password._secret = config.sops.secrets."lidarr/password".path; }; }; prowlarr = { enable = true; config = { apiKey._secret = config.sops.secrets."prowlarr/api_key".path; hostConfig.password._secret = config.sops.secrets."prowlarr/password".path; indexers = [ { name = "DrunkenSlug"; apiKey._secret = config.sops.secrets."indexer-api-keys/DrunkenSlug".path; } { name = "NZBFinder"; apiKey._secret = config.sops.secrets."indexer-api-keys/NZBFinder".path; } { name = "NzbPlanet"; apiKey._secret = config.sops.secrets."indexer-api-keys/NzbPlanet".path; } ]; }; }; sabnzbd = { enable = true; settings = { misc = { api_key._secret = config.sops.secrets."sabnzbd/api_key".path; nzb_key._secret = config.sops.secrets."sabnzbd/nzb_key".path; }; servers = [ { name = "Eweka"; host = "sslreader.eweka.nl"; port = 563; username._secret = config.sops.secrets."usenet/eweka/username".path; password._secret = config.sops.secrets."usenet/eweka/password".path; connections = 20; ssl = true; priority = 0; retention = 3000; } { name = "NewsgroupDirect"; host = "news.newsgroupdirect.com"; port = 563; username._secret = config.sops.secrets."usenet/newsgroupdirect/username".path; password._secret = config.sops.secrets."usenet/newsgroupdirect/password".path; connections = 10; ssl = true; priority = 1; optional = true; backup = true; } ]; }; }; jellyfin = { enable = true; apiKey._secret = config.sops.secrets."jellyfin/api_key".path; users = { admin = { mutable = false; policy.isAdministrator = true; password._secret = config.sops.secrets."jellyfin/alice_password".path; }; }; }; seerr = { enable = true; apiKey._secret = config.sops.secrets."seerr/api_key".path; }; vpn = { enable = true; wgConfFile = config.sops.secrets."wireguard/conf".path; accessibleFrom = [ "192.168.1.0/24" ]; }; }; } ``` -------------------------------- ### Install Nixflix Without Flakes (fetchFromGitHub) Source: https://context7.com/kiriwalawren/nixflix/llms.txt Integrate Nixflix into your NixOS configuration without flakes by fetching it from GitHub using pkgs.fetchFromGitHub. Ensure you pin to a specific commit hash and provide the correct sha256 hash. ```nix { pkgs, ... }: let nixflix = import (pkgs.fetchFromGitHub { owner = "kiriwalawren"; repo = "nixflix"; rev = "abc123def456"; # pin to a commit hash sha256 = "sha256-"; # obtained from first failed build }) { inherit pkgs; }; in { imports = [ nixflix.nixosModules.default ]; } ``` -------------------------------- ### Add Nixflix using npins Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md Add Nixflix to your npins configuration and then import the module. Ensure you have npins installed and configured. ```bash npins add github kiriwalawren nixflix --branch main ``` ```nix { pkgs, ... }: let sources = import path/to/npins/folder; nixflix = import sources.nixflix { inherit pkgs; }; in { imports = [ nixflix.nixosModules.default ]; } ``` -------------------------------- ### Get Hashes for Nix Store Prefetch Source: https://context7.com/kiriwalawren/nixflix/llms.txt Use these bash commands to obtain the necessary hashes for plugin manifests and zip archives when configuring Nixflix Jellyfin plugins. ```bash # Hash for a plugin zip (use --unpack for zip archives) nix store prefetch-file --json --unpack "https://example.com/plugin.zip" | jq -r .hash ``` ```bash # Hash for a manifest JSON file nix store prefetch-file --json "https://example.com/manifest.json" | jq -r .hash ``` -------------------------------- ### Install Nixflix Without Flakes (fetchTarball) Source: https://context7.com/kiriwalawren/nixflix/llms.txt Include Nixflix in your NixOS configuration without using flakes by fetching it directly using builtins.fetchTarball. ```nix # configuration.nix { pkgs, ... }: let nixflix = import (builtins.fetchTarball "https://github.com/kiriwalawren/nixflix/archive/main.tar.gz" ) { inherit pkgs; }; in { imports = [ nixflix.nixosModules.default ]; } ``` -------------------------------- ### Interact with Nix VM Test Driver Source: https://github.com/kiriwalawren/nixflix/blob/main/tests/README.md Python commands to control and inspect a NixOS VM during interactive testing. Use these to start services, check their status, and verify network connectivity. ```python >>> start_all() >>> machine.wait_for_unit("sonarr.service") >>> machine.succeed("curl http://127.0.0.1:8989") >>> machine.screenshot("screenshot.png") ``` -------------------------------- ### Customize Service Subdomain or Exclude from Reverse Proxy Source: https://context7.com/kiriwalawren/nixflix/llms.txt Override the default subdomain for a specific Nixflix service or completely remove it from the reverse proxy configuration. For example, Sonarr can be accessed at `tv.` instead of `sonarr.`. ```nix { nixflix.sonarr = { subdomain = "tv"; # accessible at tv. instead of sonarr. reverseProxy.expose = false; # remove from reverse proxy entirely }; } ``` -------------------------------- ### Configure Jellyfin Plugin Repository and Settings Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/jellyfin-plugins.md This Nix configuration sets up a plugin repository for Jellyfin and defines specific settings for the 'Intro Skipper' plugin. It includes options for enabling the repository, specifying plugin versions and hashes, and configuring various plugin behaviors like auto-detection, analysis parameters, and pattern matching for different content types. ```nix let fromRepo = nixflix.lib.jellyfinPlugins.fromRepo; in { nixflix.jellyfin = { system.pluginRepositories = { "Intro Skipper" = { url = "https://raw.githubusercontent.com/intro-skipper/manifest/main/10.11/manifest.json"; hash = "sha256-"; enabled = true; }; }; plugins."Intro Skipper" = { package = fromRepo { version = "1.10.11.17"; hash = "sha256-"; }; config = { ExcludeSeries = ""; AutoDetectIntros = true; AnalyzeSeasonZero = false; PreferChromaprint = false; CacheFingerprints = true; UseAlternativeBlackFrameAnalyzer = false; UpdateMediaSegments = true; RebuildMediaSegments = true; ScanIntroduction = true; ScanCredits = true; ScanRecap = true; ScanPreview = true; ScanCommercial = false; AnalysisPercent = "25"; AnalysisLengthLimit = "10"; FullLengthChapters = false; SkipFirstEpisode = false; SkipFirstEpisodeAnime = false; MinimumIntroDuration = "15"; MaximumIntroDuration = "120"; MinimumCreditsDuration = "15"; MaximumCreditsDuration = "450"; MaximumMovieCreditsDuration = "900"; MinimumRecapDuration = "15"; MaximumRecapDuration = "120"; MinimumPreviewDuration = "15"; MaximumPreviewDuration = "120"; MinimumCommercialDuration = "15"; MaximumCommercialDuration = "120"; BlackFrameMinimumPercentage = "85"; BlackFrameThreshold = "28"; UseChapterMarkersBlackFrame = true; AdjustIntroBasedOnChapters = true; AdjustIntroBasedOnSilence = true; SnapToKeyframe = true; EndSnapThreshold = "2"; AdjustWindowInward = "5"; AdjustWindowOutward = "2"; ChapterAnalyzerIntroductionPattern = "(^|\\s)(Intro|Introduction|OP|Opening)(?!\\sEnd)(\\s|$)"; ChapterAnalyzerEndCreditsPattern = "(^|\\s)(Credits?|ED|Ending|Outro)(?!\\sEnd)(\\s|$)"; ChapterAnalyzerPreviewPattern = "(^|\\s)(Preview|PV|Sneak\\s?Peek|Coming\\s?(Up|Soon)|Next\\s+(time|on|episode)|Extra|Teaser|Trailer)(?!\\sEnd)(\\s:|$)"; ChapterAnalyzerRecapPattern = "(^|\\s)(Re?cap|Sum{1,2}ary|Prev(ious(ly)?)?|(Last|Earlier)(\\s\\w+)?|Catch[ -]up)(?!\\sEnd)(\\s:|$)"; ChapterAnalyzerCommercialPattern = "(^|\\s)(Ad(vert(isement)?)?|Commercial)(?!\\sEnd)(\\s|$)"; IntroEndOffset = "0"; IntroStartOffset = "0"; MaximumFingerprintPointDifferences = 6; MaximumTimeSkip = 3.5; InvertedIndexShift = 2; SilenceDetectionMaximumNoise = "-50"; SilenceDetectionMinimumDuration = "0.33"; MaxParallelism = "2"; ProcessThreads = "0"; ProcessPriority = "BelowNormal"; UseFileTransformationPlugin = false; SkipbuttonHideDelay = "8"; EnableMainMenu = true; FileTransformationPluginEnabled = false; }; }; }; } ``` -------------------------------- ### Configure Jellyfin Plugins with Nixflix Source: https://context7.com/kiriwalawren/nixflix/llms.txt Register plugin repositories and configure individual plugins like Intro Skipper and subtitle fetchers. Ensure you obtain the correct hashes for manifests and plugin archives. ```nix let fromRepo = nixflix.lib.jellyfinPlugins.fromRepo; in { nixflix.jellyfin = { system.pluginRepositories = { "Intro Skipper" = { url = "https://raw.githubusercontent.com/intro-skipper/manifest/main/10.11/manifest.json"; hash = "sha256-"; enabled = true; }; }; plugins = { "Intro Skipper" = { package = fromRepo { version = "1.10.11.17"; hash = "sha256-"; }; config = { AutoDetectIntros = true; ScanIntroduction = true; ScanCredits = true; MinimumIntroDuration = "15"; MaximumIntroDuration = "120"; SkipbuttonHideDelay = "8"; EnableMainMenu = true; MaxParallelism = "2"; }; }; # Built-in named subtitle plugins subbuzz = { enable = true; config = { OpenSubUserName = "myusername"; OpenSubPassword._secret = config.sops.secrets."opensubtitles/password".path; OpenSubApiKey._secret = config.sops.secrets."opensubtitles/api_key".path; EnableOpenSubtitles = true; EnableYifySubtitles = true; Cache.SubLifeInMinutes = "Always"; }; }; "Open Subtitles" = { enable = true; config = { Username = "myusername"; Password._secret = config.sops.secrets."opensubtitles/password".path; }; }; "Subtitle Extract" = { enable = true; config.ExtractionDuringLibraryScan = true; }; }; }; } ``` -------------------------------- ### Import Nixflix with pkgs.fetchFromGitHub Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md Import the Nixflix module using pkgs.fetchFromGitHub. Replace the placeholder SHA256 hash with the actual hash after a rebuild error. You can pin to a specific commit using the 'rev' attribute. ```nix { pkgs, ... }: let nixflix = import (pkgs.fetchFromGitHub { owner = "kiriwalawren"; repo = "nixflix"; rev = "main"; # You can use the rev to pin the module to a specific commit using its hash sha256 = ""; # replace with the actual hash which will likely be returned after your rebuild errors out. }) { inherit pkgs; }; in { imports = [ nixflix.nixosModules.default ]; } ``` -------------------------------- ### Configure Jellyfin Subtitle Plugins Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/jellyfin-subtitles.md Set up subtitle plugins like Subbuzz and Open Subtitles for Jellyfin. This includes enabling plugins, configuring API keys and credentials, and setting subtitle fetcher preferences. ```nix {config, ...}: { sops.secrets."opensubtitles-com/api-key" = { }; sops.secrets."opensubtitles-com/password" = { }; nixflix.jellyfin = { enable = true; plugins = { subbuzz = { enable = true; config = { OpenSubUserName = "kiriwalawren"; OpenSubPassword._secret = config.sops.secrets."opensubtitles-com/password".path; OpenSubApiKey._secret = config.sops.secrets."opensubtitles-com/api-key".path; EnableOpenSubtitles = true; EnableYifySubtitles = true; Cache.SubLifeInMinutes = "Always"; # Default is "1 week"; }; }; "Open Subtitles" = { enable = true; config = { Username = "kiriwalawren"; Password._secret = config.sops.secrets."opensubtitles-com/password".path; }; }; "Subtitle Extract" = { enable = true; config.ExtractionDuringLibraryScan = true; }; }; # Optional libraries = let subtitleSettings = { disabledSubtitleFetchers = ["subbuzz"]; # Default: [] subtitleFetcherOrder = ["subbuzz" "Open Subtitles"]; # Default: ["Open Subtitles" "subbuzz"] subtitleDownloadLanguages = [ "eng" "spa" ]; # Default: [] saveSubtitlesWithMedia = true; allowEmbeddedSubtitles = "AllowAll"; requirePerfectSubtitleMatch = true; skipSubtitlesIfAudioTrackMatches = false; skipSubtitlesIfEmbeddedsubtitlesPresent = true; }; in { Shows = subtitleSettings; Anime = subtitleSettings; Movies = subtitleSettings; }; }; } ``` -------------------------------- ### Enable and Configure Seerr Media Request System Source: https://context7.com/kiriwalawren/nixflix/llms.txt Integrate Seerr with Jellyfin, Radarr, and Sonarr. API keys are managed via SOPS secrets. Custom Radarr and Sonarr instances can be specified. ```nix { nixflix.seerr = { enable = true; apiKey._secret = config.sops.secrets."seerr/api_key".path; # Custom Radarr instances (auto-discovered by default) radarr = { main = { isDefault = true; is4k = false; # apiKey, baseUrl auto-set from nixflix.radarr if enabled }; }; # Custom Sonarr instances sonarr = { main = { isDefault = true; is4k = false; }; }; openFirewall = false; # default port 5055 vpn.enable = false; }; } ``` -------------------------------- ### Fetch Plugin Hash with Nix Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/jellyfin-plugins.md Use this bash command to prefetch and unpack a plugin zip file to obtain its content hash, which is required for Nix configuration. ```bash nix store prefetch-file --json --unpack "https://example.com/plugin.zip" | jq -r .hash ``` -------------------------------- ### Enable PostgreSQL Backend for Nixflix Services Source: https://context7.com/kiriwalawren/nixflix/llms.txt Activate a shared PostgreSQL instance for all Arr services and Seerr. Nixflix automatically provisions databases, users, and ownership. Note that data is stored in `nixflix.stateDir/postgres` if `stateDir` is not `/var/lib`. ```nix { nixflix.postgres.enable = true; # Stores data in nixflix.stateDir/postgres when stateDir != /var/lib } ``` -------------------------------- ### Configure SABnzbd Usenet Client Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enables and configures SABnzbd, auto-wiring it to Arr services. API keys and Usenet provider credentials must be provided as secrets. Server configurations include connection details and priority. ```nix { nixflix.usenetClients.sabnzbd = { enable = true; settings = { misc = { api_key._secret = config.sops.secrets."sabnzbd/api_key".path; nzb_key._secret = config.sops.secrets."sabnzbd/nzb_key".path; }; servers = [ { name = "Eweka"; host = "sslreader.eweka.nl"; port = 563; username._secret = config.sops.secrets."usenet/eweka/username".path; password._secret = config.sops.secrets."usenet/eweka/password".path; connections = 20; ssl = true; priority = 0; retention = 3000; } { name = "BackupProvider"; host = "news.example.com"; port = 563; username._secret = config.sops.secrets."usenet/backup/username".path; password._secret = config.sops.secrets."usenet/backup/password".path; connections = 10; ssl = true; priority = 1; optional = true; backup = true; } ]; }; }; } ``` -------------------------------- ### Configure Jellyfin Subtitle Settings Per Library Source: https://context7.com/kiriwalawren/nixflix/llms.txt Define subtitle fetcher order, languages, and download preferences for different Jellyfin libraries. Apply a consistent set of settings across multiple libraries. ```nix { nixflix.jellyfin.libraries = let subtitleSettings = { subtitleFetcherOrder = [ "subbuzz" "Open Subtitles" ]; disabledSubtitleFetchers = []; subtitleDownloadLanguages = [ "eng" "spa" ]; saveSubtitlesWithMedia = true; allowEmbeddedSubtitles = "AllowAll"; requirePerfectSubtitleMatch = false; skipSubtitlesIfAudioTrackMatches = false; skipSubtitlesIfEmbeddedSubtitlesPresent = true; }; in { Shows = subtitleSettings; Anime = subtitleSettings; Movies = subtitleSettings; }; } ``` -------------------------------- ### Configure Jellyfin Libraries Source: https://context7.com/kiriwalawren/nixflix/llms.txt Define or override Jellyfin media library settings, including collection types, media paths, metadata preferences, and subtitle language options. This allows for fine-grained control over how your media is organized and presented. ```nix { config, pkgs, ... }: { nixflix.jellyfin.libraries = { # Override auto-generated library settings Movies = { collectionType = "movies"; paths = [ "/data/media/movies" "/data/media/movies-4k" ]; preferredMetadataLanguage = "en"; metadataCountryCode = "US"; enableRealtimeMonitor = true; subtitleDownloadLanguages = [ "eng" "spa" ]; saveSubtitlesWithMedia = true; typeOptions = [ { type = "Movie"; metadataFetchers = [ "TheMovieDb" "The Open Movie Database" ]; imageFetchers = [ "TheMovieDb" ]; } ]; }; Shows = { collectionType = "tvshows"; paths = [ "/data/media/tv" ]; seasonZeroDisplayName = "Specials"; enableAutomaticSeriesGrouping = true; }; # Remove an auto-generated library entirely # Music = lib.mkForce {}; }; } ``` -------------------------------- ### Enter Nix Development Shell Source: https://github.com/kiriwalawren/nixflix/blob/main/README.md Use this command to enter the development shell for the Nixflix project. This provides an environment with all necessary tools and dependencies for development. ```bash nix develop ``` -------------------------------- ### Import Nixflix with builtins.fetchTarball Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md Use this method to import the Nixflix module without using flakes. Pin the module to a specific commit by replacing 'main' with the commit hash. ```nix { pkgs, ... }: let nixflix = import (builtins.fetchTarball "https://github.com/kiriwalawren/nixflix/archive/main.tar.gz") { inherit pkgs; }; # You can pin the module to a specific commit by replacing main with the commit's hash in { imports = [ nixflix.nixosModules.default ]; } ``` -------------------------------- ### Configure Core Global Nixflix Options Source: https://context7.com/kiriwalawren/nixflix/llms.txt Set top-level options for Nixflix, including enabling the service, defining media directories, specifying additional users for the media group, setting service dependencies, and enabling theme.park UI theming. ```nix { nixflix = { enable = true; # Directories (parent dirs must be root-owned with execute permission for all) mediaDir = "/data/media"; # default: /data/media downloadsDir = "/data/downloads"; # default: /data/downloads stateDir = "/var/lib"; # default: /var/lib # Extra OS users added to the shared "media" group mediaUsers = [ "myuser" ]; # Wait for these systemd units before starting any nixflix service serviceDependencies = [ "unlock-raid.service" "tailscale.service" ]; # theme.park UI theming (requires a reverse proxy for all services except Jellyfin) theme = { enable = true; name = "overseerr"; # any official or community theme.park theme }; }; } ``` -------------------------------- ### Basic Nixflix Configuration Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/index.md This is a basic Nixflix configuration that enables Nixflix and several popular media server services like Sonarr, Prowlarr, SABnzbd, and Jellyfin. It shows how to specify directories and API keys using secrets. ```nix { nixflix = { enable = true; mediaDir = "/data/media"; stateDir = "/var/lib"; sonarr = { enable = true; config.apiKey = {_secret = "/run/secrets/sonarr-api-key";}; }; prowlarr = { enable = true; config.apiKey = {_secret = "/run/secrets/prowlarr-api-key";}; }; sabnzbd = { enable = true; settings.misc.api_key = {_secret = "/run/secrets/sabnzbd-api-key";}; }; jellyfin.enable = true; }; } ``` -------------------------------- ### Check Nix Formatting and Linting Source: https://github.com/kiriwalawren/nixflix/blob/main/README.md Execute this command to check the code formatting and linting rules for the Nix project. It helps identify any style violations or potential issues. ```bash nix flake check ``` -------------------------------- ### List Available Nix Tests Source: https://github.com/kiriwalawren/nixflix/blob/main/tests/README.md Use this command to list all available tests for your NixOS configuration. It helps in identifying the names of tests that can be run individually or in groups. ```bash nix eval --json '.#checks.x86_64-linux' --apply builtins.attrNames ``` -------------------------------- ### Nix Development Commands Source: https://context7.com/kiriwalawren/nixflix/llms.txt Common development commands for the Nix project, including entering the development shell, formatting code, running checks, and building/serving documentation. ```bash # Enter the development shell nix develop # Format all Nix files nix fmt # Run checks (formatting + linting + tests + docs build) nix flake check # Build the documentation site nix build .#docs # Serve documentation locally nix run .#docs-serve ``` -------------------------------- ### Format Nix Code Source: https://github.com/kiriwalawren/nixflix/blob/main/README.md Run this command to format all Nix code within the project according to the project's style guidelines. This ensures code consistency. ```bash nix fmt ``` -------------------------------- ### Pin Manifest Hash with Nix Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/jellyfin-plugins.md This bash command fetches a manifest JSON file and extracts its hash using jq, which is used to pin the plugin repository source in Nix configurations. ```bash nix store prefetch-file --json "https://example.com/manifest.json" | jq -r .hash ``` -------------------------------- ### Add Nixflix as a flake input Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md Configure your flake.nix to include Nixflix as an input. Ensure that nixpkgs is followed by the nixflix input for compatibility. ```nix { description = "My NixOS Configuration"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixflix = { url = "github:kiriwalawren/nixflix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, nixflix, ... }: { nixosConfigurations.yourhost = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./configuration.nix nixflix.nixosModules.default ]; }; }; } ``` -------------------------------- ### Configure Recyclarr with Nix Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enable and configure Recyclarr for quality profile syncing. Specify desired quality settings for Radarr and Sonarr, and optionally enable cleanup of unmanaged profiles. ```nix { "nixflix.recyclarr" = { enable = true; radarrQuality = "1080p"; # or "4K" → creates "[SQP] SQP-1 (2160p)" profile sonarrQuality = "1080p"; # or "4K" → creates "WEB-2160p (Alternative)" profile # Remove any quality profiles NOT in this managed list cleanupUnmanagedProfiles = { enable = true; # managedProfiles is auto-set from radarrQuality/sonarrQuality/anime # Override to keep additional custom profiles: # managedProfiles = [ "[SQP] SQP-1 (1080p)" "My Custom Profile" ]; }; # Full recyclarr YAML config expressed in Nix (optional — for advanced use) config = { sonarr.sonarr = { base_url = "http://127.0.0.1:8989"; api_key = { _secret = "/run/secrets/sonarr_api_key"; }; quality_profiles = [ { name = "WEB-1080p (Alternative)"; } ]; # quality_profiles = lib.mkForce []; # disable auto-generated profiles }; }; }; } ``` -------------------------------- ### Enable Flakes in NixOS configuration Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/getting-started/index.md Add this snippet to your NixOS configuration to enable experimental features for Nix command and flakes. ```nix { ... }: { nix.settings.experimental-features = ["nix-command" "flakes"]; } ``` -------------------------------- ### Nixflix Directory Structure Source: https://github.com/kiriwalawren/nixflix/blob/main/docs/examples/basic-setup.md This is the standard directory structure for Nixflix, organizing media, downloads, and service state files. ```bash /data/ ├── media/ │ ├── music/ # Music → Jellyfin "Music" library │ ├── anime/ # Anime series → Jellyfin "Shows" library │ ├── movies/ # Movies → Jellyfin "Movies" library │ └── tv/ # Standard TV shows → Jellyfin "Shows" library ├── downloads/ │ └── usenet/ │ ├── complete/ │ └── incomplete/ └── .state/ ├── jellyfin/ ├── lidarr/ ├── postgres/ ├── prowlarr/ ├── radarr/ ├── seerr/ ├── sonarr/ └── sonarr-anime/ ``` -------------------------------- ### Run Nix VM Test Interactively Source: https://github.com/kiriwalawren/nixflix/blob/main/tests/README.md Debug VM tests by running them interactively. This allows you to control the virtual machine and inspect its state during the test execution. ```bash nix build .#checks.x86_64-linux.sonarr-basic.driverInteractive ./result/bin/nixos-test-driver ``` -------------------------------- ### Configure Nginx Reverse Proxy with Nixflix Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enable and configure Nginx as a subdomain-based reverse proxy for Nixflix services. Options include setting the domain, adding host entries, and enforcing SSL. Note that `security.acme.certs.nixflix` must be set if `enableACME` is true. ```nix { nixflix = { # --- Option A: nginx --- nginx = { enable = true; domain = "nixflix"; # services at .nixflix addHostsEntries = true; # adds 127.0.0.1 entries if no DNS forceSSL = false; enableACME = false; # set security.acme.certs.nixflix if true }; # --- Option B: Caddy --- # caddy = { # enable = true; # domain = "home.example.com"; # addHostsEntries = false; # tls = { # enable = true; # acmeEmail = "me@example.com"; # internal = false; # true = self-signed CA # }; # }; }; } ``` -------------------------------- ### Configure Sonarr Service Source: https://context7.com/kiriwalawren/nixflix/llms.txt Enables and configures the Sonarr service, including API credentials, host settings, root folders, and delay profiles. Ensure API keys and passwords are provided as secrets. ```nix { nixflix.sonarr = { enable = true; # API credentials (never put plain values here — use _secret) config = { apiKey._secret = config.sops.secrets."sonarr/api_key".path; hostConfig = { port = 8989; # default for sonarr password._secret = config.sops.secrets."sonarr/password".path; username = "sonarr"; # default login username branch = "main"; bindAddress = "127.0.0.1"; instanceName = "Sonarr"; logLevel = "info"; analyticsEnabled = false; urlBase = ""; proxyEnabled = false; }; # Root folders – auto-created on disk rootFolders = [ { path = "/data/media/tv"; } { path = "/data/media/tv-hd"; } ]; # TRaSH-guide delay profiles delayProfiles = [ { enableUsenet = true; enableTorrent = false; usenetDelay = 0; torrentDelay = 0; order = 2000; tags = []; preferredProtocol = "usenet"; bypassIfHighestQuality = true; } ]; }; # Override which directories are managed for this service mediaDirs = [ "/data/media/tv" "/data/media/tv-4k" ]; # Route service traffic through VPN namespace vpn.enable = false; # Open firewall port directly (not needed if using reverse proxy) openFirewall = false; # Advanced: pass extra env-var based config (stored in Nix store, no secrets!) settings = { server.urlBase = ""; log.analyticsEnabled = false; }; }; } ``` -------------------------------- ### Add New Nix Unit Test Source: https://github.com/kiriwalawren/nixflix/blob/main/tests/README.md Structure for adding a new unit test in Nix. This involves evaluating a configuration and asserting conditions to verify correct service generation. ```nix { # ... existing tests my-unit-test = let config = evalConfig [ { services.nixflix = { # ... your config }; } ]; # ... assertions in assertTest "my-unit-test" (/* condition */); } ``` -------------------------------- ### Configure WireGuard VPN for Service Confinement Source: https://context7.com/kiriwalawren/nixflix/llms.txt Set up a WireGuard VPN to confine selected services within a network namespace, including an automatic kill switch. Specify accessible subnets and forwarded ports. ```nix { nixflix.vpn = { enable = true; wgConfFile = config.sops.secrets."wireguard/conf".path; # wg-quick .conf # Which subnets in the default namespace can reach VPN-confined services accessibleFrom = [ "192.168.1.0/24" ]; # Open forwarded ports through the VPN interface (for port-forwarding VPNs) openVPNPorts = [ { port = 60729; protocol = "both"; } ]; }; # Opt individual services into the VPN namespace nixflix.sonarr.vpn.enable = true; nixflix.radarr.vpn.enable = true; nixflix.prowlarr.vpn.enable = true; nixflix.torrentClients.qbittorrent.vpn.enable = true; # Starr apps advise keeping Prowlarr outside VPN (TRaSH Guides) # nixflix.prowlarr.vpn.enable = false; # default } ```