{ config, service_configs, ... }: { services.arrInit = { prowlarr = { enable = true; serviceName = "prowlarr"; port = service_configs.ports.private.prowlarr.port; dataDir = service_configs.prowlarr.dataDir; apiVersion = "v1"; networkNamespacePath = "/run/netns/wg"; networkNamespaceService = "wg"; # Guarantee critical config.xml elements before startup. Prowlarr has a # history of losing from config.xml, causing the service to run # without binding any socket. See arr-init's configXml for details. configXml = { Port = service_configs.ports.private.prowlarr.port; BindAddress = "*"; EnableSsl = false; }; # Prowlarr runs in the wg netns; Sonarr/Radarr in the host netns. # From host netns, Prowlarr is reachable at the wg namespace address, # not at localhost (which resolves to the host's own netns). # Health checks can now run — the reverse-connect is reachable. healthChecks = true; syncedApps = [ { name = "Sonarr"; implementation = "Sonarr"; configContract = "SonarrSettings"; prowlarrUrl = "http://${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.private.prowlarr.port}"; baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.private.sonarr.port}"; apiKeyFrom = "${service_configs.sonarr.dataDir}/config.xml"; serviceName = "sonarr"; } { name = "Radarr"; implementation = "Radarr"; configContract = "RadarrSettings"; prowlarrUrl = "http://${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.private.prowlarr.port}"; baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.private.radarr.port}"; apiKeyFrom = "${service_configs.radarr.dataDir}/config.xml"; serviceName = "radarr"; } ]; }; sonarr = { enable = true; serviceName = "sonarr"; port = service_configs.ports.private.sonarr.port; dataDir = service_configs.sonarr.dataDir; healthChecks = true; configXml = { Port = service_configs.ports.private.sonarr.port; BindAddress = "*"; EnableSsl = false; }; rootFolders = [ service_configs.media.tvDir ]; naming = { renameEpisodes = true; replaceIllegalCharacters = true; standardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}"; dailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Full}"; animeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}"; seasonFolderFormat = "Season {season}"; seriesFolderFormat = "{Series Title}"; }; downloadClients = [ { name = "qBittorrent"; implementation = "QBittorrent"; configContract = "QBittorrentSettings"; serviceName = "qbittorrent"; fields = { host = config.vpnNamespaces.wg.namespaceAddress; port = service_configs.ports.private.torrent.port; useSsl = false; tvCategory = "tvshows"; }; } ]; }; radarr = { enable = true; serviceName = "radarr"; port = service_configs.ports.private.radarr.port; dataDir = service_configs.radarr.dataDir; healthChecks = true; configXml = { Port = service_configs.ports.private.radarr.port; BindAddress = "*"; EnableSsl = false; }; rootFolders = [ service_configs.media.moviesDir ]; naming = { renameMovies = true; replaceIllegalCharacters = true; standardMovieFormat = "{Movie Title} ({Release Year}) {Quality Full}"; movieFolderFormat = "{Movie Title} ({Release Year})"; }; downloadClients = [ { name = "qBittorrent"; implementation = "QBittorrent"; configContract = "QBittorrentSettings"; serviceName = "qbittorrent"; fields = { host = config.vpnNamespaces.wg.namespaceAddress; port = service_configs.ports.private.torrent.port; useSsl = false; movieCategory = "movies"; }; } ]; }; }; services.bazarrInit = { enable = true; dataDir = "/var/lib/bazarr"; port = service_configs.ports.private.bazarr.port; sonarr = { enable = true; dataDir = service_configs.sonarr.dataDir; port = service_configs.ports.private.sonarr.port; serviceName = "sonarr"; }; radarr = { enable = true; dataDir = service_configs.radarr.dataDir; port = service_configs.ports.private.radarr.port; serviceName = "radarr"; }; }; services.jellyseerrInit = { enable = true; configDir = service_configs.jellyseerr.configDir; radarr = { profileName = "Remux + WEB 2160p"; dataDir = service_configs.radarr.dataDir; port = service_configs.ports.private.radarr.port; serviceName = "radarr"; }; sonarr = { profileName = "WEB-2160p"; dataDir = service_configs.sonarr.dataDir; port = service_configs.ports.private.sonarr.port; serviceName = "sonarr"; }; }; }