From 384f1b222feff814e9e92c8fb0f51467c94c6763 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Wed, 9 Jul 2025 21:36:43 +0100 Subject: [PATCH] Add radarr, sonarr Signed-off-by: Nikolaos Karaolidis --- .../console/podman/authelia/default.nix | 26 +- .../configs/console/podman/gitea/default.nix | 24 +- .../console/podman/grafana/default.nix | 9 +- .../configs/console/podman/media/default.nix | 331 +++++++++++++++++- .../media/jellyfin/libraries/music/Music.json | 229 ------------ .../console/podman/media/prowlarr/setup.sh | 34 +- .../console/podman/media/radarr/setup.sh | 32 ++ .../console/podman/media/sonarr/setup.sh | 32 ++ .../console/podman/nextcloud/default.nix | 24 +- .../configs/console/podman/ntfy/default.nix | 9 +- .../console/podman/outline/default.nix | 26 +- .../configs/console/podman/shlink/default.nix | 33 +- .../configs/console/podman/sish/default.nix | 9 +- .../console/podman/traefik/default.nix | 25 +- .../console/podman/transmission/default.nix | 9 +- .../console/podman/vaultwarden/default.nix | 24 +- packages/default.nix | 2 + packages/docker/prowlarr/entrypoint.sh | 2 +- packages/docker/radarr/default.nix | 43 +++ packages/docker/radarr/entrypoint.sh | 41 +++ packages/docker/sonarr/default.nix | 43 +++ packages/docker/sonarr/entrypoint.sh | 41 +++ 22 files changed, 750 insertions(+), 298 deletions(-) delete mode 100644 hosts/jupiter/users/storm/configs/console/podman/media/jellyfin/libraries/music/Music.json create mode 100644 hosts/jupiter/users/storm/configs/console/podman/media/radarr/setup.sh create mode 100644 hosts/jupiter/users/storm/configs/console/podman/media/sonarr/setup.sh create mode 100644 packages/docker/radarr/default.nix create mode 100644 packages/docker/radarr/entrypoint.sh create mode 100644 packages/docker/sonarr/default.nix create mode 100644 packages/docker/sonarr/entrypoint.sh diff --git a/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix b/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix index aeeeb55..fb015d0 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/authelia/default.nix @@ -182,11 +182,18 @@ in ]; }; - unitConfig.After = [ - "${containers.authelia-postgresql._serviceName}.service" - "${containers.authelia-redis._serviceName}.service" - "sops-nix.service" - ]; + unitConfig = + let + dependencies = [ + "${containers.authelia-postgresql._serviceName}.service" + "${containers.authelia-redis._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; authelia-postgresql = { @@ -201,7 +208,14 @@ in environmentFiles = [ hmConfig.sops.templates.authelia-postgresql-env.path ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig = + let + dependencies = [ "sops-nix.service" ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; authelia-redis.containerConfig = { diff --git a/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix b/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix index d6244bb..520b07d 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/gitea/default.nix @@ -237,10 +237,17 @@ in ]; }; - unitConfig.After = [ - "${containers.gitea-postgresql._serviceName}.service" - "sops-nix.service" - ]; + unitConfig = + let + dependencies = [ + "${containers.gitea-postgresql._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; gitea-postgresql = { @@ -255,7 +262,14 @@ in environmentFiles = [ hmConfig.sops.templates.gitea-postgresql-env.path ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig = + let + dependencies = [ "sops-nix.service" ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; authelia.containerConfig.volumes = [ diff --git a/hosts/jupiter/users/storm/configs/console/podman/grafana/default.nix b/hosts/jupiter/users/storm/configs/console/podman/grafana/default.nix index 479960e..9afdd18 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/grafana/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/grafana/default.nix @@ -139,7 +139,14 @@ in ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig = + let + dependencies = [ "sops-nix.service" ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; grafana-image-renderer.containerConfig = { diff --git a/hosts/jupiter/users/storm/configs/console/podman/media/default.nix b/hosts/jupiter/users/storm/configs/console/podman/media/default.nix index 09b33c3..d68e21b 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/media/default.nix +++ b/hosts/jupiter/users/storm/configs/console/podman/media/default.nix @@ -12,7 +12,7 @@ let selfPkgs = inputs.self.packages.${system}; hmConfig = config.home-manager.users.${user}; - inherit (hmConfig.virtualisation.quadlet) volumes networks; + inherit (hmConfig.virtualisation.quadlet) containers volumes networks; jellyfinAutheliaClientId = "59TRpNutxEeRRCAZbDsK7rsnrA5NC69HAdAO45CEfc740xl4hgIacDy2u03oiFc89Exb67udBQvmfwxgeAQtJPiNAJxA5OzGmdQf"; in @@ -24,7 +24,6 @@ in "d /mnt/storage/private/storm/containers/storage/volumes/media/_data/shows 755 storm storm" "d /mnt/storage/private/storm/containers/storage/volumes/media/_data/anime-films 755 storm storm" "d /mnt/storage/private/storm/containers/storage/volumes/media/_data/anime-shows 755 storm storm" - "d /mnt/storage/private/storm/containers/storage/volumes/media/_data/music 755 storm storm" ]; sops = { @@ -34,6 +33,11 @@ in "jellyfin/authelia/digest".sopsFile = ../../../../../../secrets/secrets.yaml; "prowlarr/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml; + + "radarr-films/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml; + "radarr-anime-films/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml; + "sonarr-shows/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml; + "sonarr-anime-shows/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml; }; templates = { @@ -79,6 +83,118 @@ in prowlarr-env.content = '' PROWLARR_API_KEY=${hmConfig.sops.placeholder."prowlarr/apiKey"} ''; + + prowlarr-radarr-films.content = builtins.readFile ( + (pkgs.formats.json { }).generate "radarr-films.json" { + enable = true; + name = "Radarr (Films)"; + implementation = "Radarr"; + configContract = "RadarrSettings"; + syncLevel = "fullSync"; + fields = [ + { + name = "prowlarrUrl"; + value = "http://prowlarr:9696"; + } + { + name = "baseUrl"; + value = "http://radarr-films:7878"; + } + { + name = "apiKey"; + value = hmConfig.sops.placeholder."radarr-films/apiKey"; + } + ]; + } + ); + + prowlarr-radarr-anime-films.content = builtins.readFile ( + (pkgs.formats.json { }).generate "radarr-anime-films.json" { + enable = true; + name = "Radarr (Anime Films)"; + implementation = "Radarr"; + configContract = "RadarrSettings"; + syncLevel = "fullSync"; + fields = [ + { + name = "prowlarrUrl"; + value = "http://prowlarr:9696"; + } + { + name = "baseUrl"; + value = "http://radarr-anime-films:7878"; + } + { + name = "apiKey"; + value = hmConfig.sops.placeholder."radarr-anime-films/apiKey"; + } + ]; + } + ); + + prowlarr-sonarr-shows.content = builtins.readFile ( + (pkgs.formats.json { }).generate "sonarr-shows.json" { + enable = true; + name = "Sonarr (Shows)"; + implementation = "Sonarr"; + configContract = "SonarrSettings"; + syncLevel = "fullSync"; + fields = [ + { + name = "prowlarrUrl"; + value = "http://prowlarr:9696"; + } + { + name = "baseUrl"; + value = "http://sonarr-shows:8989"; + } + { + name = "apiKey"; + value = hmConfig.sops.placeholder."sonarr-shows/apiKey"; + } + ]; + } + ); + + prowlarr-sonarr-anime-shows.content = builtins.readFile ( + (pkgs.formats.json { }).generate "sonarr-anime-shows.json" { + enable = true; + name = "Sonarr (Anime Shows)"; + implementation = "Sonarr"; + configContract = "SonarrSettings"; + syncLevel = "fullSync"; + fields = [ + { + name = "prowlarrUrl"; + value = "http://prowlarr:9696"; + } + { + name = "baseUrl"; + value = "http://sonarr-anime-shows:8989"; + } + { + name = "apiKey"; + value = hmConfig.sops.placeholder."sonarr-anime-shows/apiKey"; + } + ]; + } + ); + + radarr-films-env.content = '' + RADARR_API_KEY=${hmConfig.sops.placeholder."radarr-films/apiKey"} + ''; + + radarr-anime-films-env.content = '' + RADARR_API_KEY=${hmConfig.sops.placeholder."radarr-anime-films/apiKey"} + ''; + + sonarr-shows-env.content = '' + SONARR_API_KEY=${hmConfig.sops.placeholder."sonarr-shows/apiKey"} + ''; + + sonarr-anime-shows-env.content = '' + SONARR_API_KEY=${hmConfig.sops.placeholder."sonarr-anime-shows/apiKey"} + ''; }; }; @@ -96,6 +212,11 @@ in jellyfin-cache = { }; prowlarr = { }; + + radarr-films = { }; + radarr-anime-films = { }; + sonarr-shows = { }; + sonarr-anime-shows = { }; }; containers = { @@ -133,7 +254,14 @@ in devices = [ "nvidia.com/gpu=all" ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig = + let + dependencies = [ "sops-nix.service" ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; flaresolverr.containerConfig = { @@ -168,18 +296,205 @@ in "${setup}:/etc/prowlarr/setup.sh:ro" "${postStart}:/etc/prowlarr/post-start.sh:ro" "${./prowlarr/indexers}:/etc/prowlarr/indexers:ro" + "${hmConfig.sops.templates.prowlarr-radarr-films.path}:/etc/prowlarr/apps/radarr-films.json:ro" + "${hmConfig.sops.templates.prowlarr-radarr-anime-films.path}:/etc/prowlarr/apps/radarr-anime-films.json:ro" + "${hmConfig.sops.templates.prowlarr-sonarr-shows.path}:/etc/prowlarr/apps/sonarr-shows.json:ro" + "${hmConfig.sops.templates.prowlarr-sonarr-anime-shows.path}:/etc/prowlarr/apps/sonarr-anime-shows.json:ro" "${volumes.prowlarr.ref}:/var/lib/prowlarr" ]; - environments.PROWLARR_URL_BASE = "/indexers"; + environments.PROWLARR_URL_BASE = "/manage/indexers"; environmentFiles = [ hmConfig.sops.templates.prowlarr-env.path ]; labels = [ "traefik.enable=true" - "traefik.http.routers.prowlarr.rule=Host(`media.karaolidis.com`) && PathPrefix(`/indexers`)" + "traefik.http.routers.prowlarr.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/indexers`)" "traefik.http.routers.prowlarr.middlewares=authelia@docker" ]; }; - unitConfig.After = [ "sops-nix.service" ]; + unitConfig = + let + dependencies = [ + "sops-nix.service" + "${containers.transmission._serviceName}.service" + "${containers.flaresolverr._serviceName}.service" + "${containers.radarr-films._serviceName}.service" + "${containers.radarr-anime-films._serviceName}.service" + "${containers.sonarr-shows._serviceName}.service" + "${containers.sonarr-anime-shows._serviceName}.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; + }; + + radarr-films = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-radarr}"; + networks = [ + networks.media.ref + networks.transmission.ref + networks.traefik.ref + ]; + volumes = + let + setup = pkgs.writeTextFile { + name = "setup.sh"; + executable = true; + text = builtins.readFile ./radarr/setup.sh; + }; + in + [ + "${setup}:/etc/radarr/setup.sh:ro" + "${volumes.radarr-films.ref}:/var/lib/radarr" + ]; + environments.RADARR_URL_BASE = "/manage/films"; + environmentFiles = [ hmConfig.sops.templates.radarr-films-env.path ]; + labels = [ + "traefik.enable=true" + "traefik.http.routers.radarr-films.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/films`)" + "traefik.http.routers.radarr-films.middlewares=authelia@docker" + ]; + }; + + unitConfig = + let + dependencies = [ + "${containers.transmission._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; + }; + + radarr-anime-films = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-radarr}"; + networks = [ + networks.media.ref + networks.transmission.ref + networks.traefik.ref + ]; + volumes = + let + setup = pkgs.writeTextFile { + name = "setup.sh"; + executable = true; + text = builtins.readFile ./radarr/setup.sh; + }; + in + [ + "${setup}:/etc/radarr/setup.sh:ro" + "${volumes.radarr-anime-films.ref}:/var/lib/radarr" + ]; + environments.RADARR_URL_BASE = "/manage/anime-films"; + environmentFiles = [ hmConfig.sops.templates.radarr-anime-films-env.path ]; + labels = [ + "traefik.enable=true" + "traefik.http.routers.radarr-anime-films.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/anime-films`)" + "traefik.http.routers.radarr-anime-films.middlewares=authelia@docker" + ]; + }; + + unitConfig = + let + dependencies = [ + "${containers.transmission._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; + }; + + sonarr-shows = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-sonarr}"; + networks = [ + networks.media.ref + networks.transmission.ref + networks.traefik.ref + ]; + volumes = + let + setup = pkgs.writeTextFile { + name = "setup.sh"; + executable = true; + text = builtins.readFile ./sonarr/setup.sh; + }; + in + [ + "${setup}:/etc/sonarr/setup.sh:ro" + "${volumes.sonarr-shows.ref}:/var/lib/sonarr" + ]; + environments.SONARR_URL_BASE = "/manage/shows"; + environmentFiles = [ hmConfig.sops.templates.sonarr-shows-env.path ]; + labels = [ + "traefik.enable=true" + "traefik.http.routers.sonarr-shows.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/shows`)" + "traefik.http.routers.sonarr-shows.middlewares=authelia@docker" + ]; + }; + + unitConfig = + let + dependencies = [ + "${containers.transmission._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; + }; + + sonarr-anime-shows = { + containerConfig = { + image = "docker-archive:${selfPkgs.docker-sonarr}"; + networks = [ + networks.media.ref + networks.transmission.ref + networks.traefik.ref + ]; + volumes = + let + setup = pkgs.writeTextFile { + name = "setup.sh"; + executable = true; + text = builtins.readFile ./sonarr/setup.sh; + }; + in + [ + "${setup}:/etc/sonarr/setup.sh:ro" + "${volumes.sonarr-anime-shows.ref}:/var/lib/sonarr" + ]; + environments.SONARR_URL_BASE = "/manage/anime-shows"; + environmentFiles = [ hmConfig.sops.templates.sonarr-anime-shows-env.path ]; + labels = [ + "traefik.enable=true" + "traefik.http.routers.sonarr-anime-shows.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/anime-shows`)" + "traefik.http.routers.sonarr-anime-shows.middlewares=authelia@docker" + ]; + }; + + unitConfig = + let + dependencies = [ + "${containers.transmission._serviceName}.service" + "sops-nix.service" + ]; + in + { + After = dependencies; + Requires = dependencies; + }; }; authelia.containerConfig.volumes = @@ -189,13 +504,13 @@ in { domain = "media.karaolidis.com"; policy = "one_factor"; - resources = [ "^/(indexers|films|shows|anime-films|anime-shows)([/?].*)?$" ]; + resources = [ "^/manage([/?].*)?$" ]; subject = [ "group:media" ]; } { domain = "media.karaolidis.com"; policy = "deny"; - resources = [ "^/(indexers|films|shows|anime-films|anime-shows)([/?].*)?$" ]; + resources = [ "^/manage([/?].*)?$" ]; } { domain = "media.karaolidis.com"; diff --git a/hosts/jupiter/users/storm/configs/console/podman/media/jellyfin/libraries/music/Music.json b/hosts/jupiter/users/storm/configs/console/podman/media/jellyfin/libraries/music/Music.json deleted file mode 100644 index 9d1ffeb..0000000 --- a/hosts/jupiter/users/storm/configs/console/podman/media/jellyfin/libraries/music/Music.json +++ /dev/null @@ -1,229 +0,0 @@ -{ - "LibraryOptions": { - "Enabled": true, - "EnableArchiveMediaFiles": false, - "EnablePhotos": true, - "EnableRealtimeMonitor": true, - "EnableLUFSScan": true, - "ExtractTrickplayImagesDuringLibraryScan": false, - "SaveTrickplayWithMedia": false, - "EnableTrickplayImageExtraction": false, - "ExtractChapterImagesDuringLibraryScan": false, - "EnableChapterImageExtraction": false, - "EnableInternetProviders": true, - "SaveLocalMetadata": true, - "EnableAutomaticSeriesGrouping": false, - "PreferredMetadataLanguage": "en", - "MetadataCountryCode": "US", - "SeasonZeroDisplayName": "Specials", - "AutomaticRefreshIntervalDays": 30, - "EnableEmbeddedTitles": false, - "EnableEmbeddedExtrasTitles": false, - "EnableEmbeddedEpisodeInfos": false, - "AllowEmbeddedSubtitles": "AllowAll", - "SkipSubtitlesIfEmbeddedSubtitlesPresent": false, - "SkipSubtitlesIfAudioTrackMatches": false, - "SaveSubtitlesWithMedia": true, - "SaveLyricsWithMedia": true, - "RequirePerfectSubtitleMatch": true, - "AutomaticallyAddToCollection": false, - "PreferNonstandardArtistsTag": false, - "UseCustomTagDelimiters": false, - "MetadataSavers": ["Nfo"], - "TypeOptions": [ - { - "Type": "MusicArtist", - "MetadataFetchers": ["MusicBrainz", "TheAudioDB"], - "MetadataFetcherOrder": ["MusicBrainz", "TheAudioDB"], - "ImageFetchers": ["TheAudioDB"], - "ImageFetcherOrder": ["TheAudioDB"], - "ImageOptions": [ - { - "Type": "Primary", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Art", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "BoxRear", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Banner", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Box", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Disc", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Logo", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Menu", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Thumb", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Backdrop", - "Limit": "1", - "MinWidth": "1280" - } - ] - }, - { - "Type": "MusicAlbum", - "MetadataFetchers": ["MusicBrainz", "TheAudioDB"], - "MetadataFetcherOrder": ["MusicBrainz", "TheAudioDB"], - "ImageFetchers": ["TheAudioDB"], - "ImageFetcherOrder": ["TheAudioDB"], - "ImageOptions": [ - { - "Type": "Primary", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Art", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "BoxRear", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Banner", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Box", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Disc", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Logo", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Menu", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Thumb", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Backdrop", - "Limit": "0", - "MinWidth": "1280" - } - ] - }, - { - "Type": "Audio", - "ImageFetchers": ["Image Extractor"], - "ImageFetcherOrder": ["Image Extractor"] - }, - { - "Type": "MusicVideo", - "ImageFetchers": ["Embedded Image Extractor", "Screen Grabber"], - "ImageFetcherOrder": ["Embedded Image Extractor", "Screen Grabber"], - "ImageOptions": [ - { - "Type": "Primary", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Art", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "BoxRear", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Banner", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Box", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Disc", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Logo", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Menu", - "Limit": 0, - "MinWidth": 0 - }, - { - "Type": "Thumb", - "Limit": 1, - "MinWidth": 0 - }, - { - "Type": "Backdrop", - "Limit": "1", - "MinWidth": "1280" - } - ] - } - ], - "LocalMetadataReaderOrder": ["Nfo"], - "SubtitleDownloadLanguages": [], - "CustomTagDelimiters": ["/", "|", ";", "\\"], - "DelimiterWhitelist": [], - "DisabledSubtitleFetchers": [], - "SubtitleFetcherOrder": [], - "DisabledLyricFetchers": [], - "LyricFetcherOrder": [], - "PathInfos": [ - { - "Path": "/var/lib/media/music" - } - ] - } -} diff --git a/hosts/jupiter/users/storm/configs/console/podman/media/prowlarr/setup.sh b/hosts/jupiter/users/storm/configs/console/podman/media/prowlarr/setup.sh index 3066b15..c31d561 100644 --- a/hosts/jupiter/users/storm/configs/console/podman/media/prowlarr/setup.sh +++ b/hosts/jupiter/users/storm/configs/console/podman/media/prowlarr/setup.sh @@ -5,13 +5,14 @@ curl -sf "$PROWLARR_HOST/api/v1/tag" \ -X POST \ -H 'Content-Type: application/json' \ -H "X-Api-Key: $PROWLARR_API_KEY" \ - --data-raw '{"label": "flaresolverr"}' + --data-raw '{"label": "flaresolverr"}' || true -curl -sf "$PROWLARR_HOST/api/v1/indexerProxy?forceSave=true" \ - -X POST \ - -H 'Content-Type: application/json' \ - -H "X-Api-Key: $PROWLARR_API_KEY" \ - --data-binary @- <' > /var/lib/radarr/config.xml + + xmlstarlet ed -L \ + -s /Config -t elem -n LaunchBrowser -v "False" \ + -s /Config -t elem -n ApiKey -v "$RADARR_API_KEY" \ + -s /Config -t elem -n AuthenticationMethod -v "External" \ + -s /Config -t elem -n AuthenticationRequired -v "DisabledForLocalAddresses" \ + -s /Config -t elem -n LogLevel -v "info" \ + -s /Config -t elem -n UrlBase -v "${RADARR_URL_BASE:-}" \ + -s /Config -t elem -n InstanceName -v "${RADARR_INSTANCE_NAME:-radarr}" \ + -s /Config -t elem -n AnalyticsEnabled -v "False" \ + /var/lib/radarr/config.xml +fi + +Radarr -data=/var/lib/radarr -nobrowser "$@" & +PID=$! + +RADARR_HOST="http://localhost:7878${RADARR_URL_BASE:-}" + +if [ ! -f /var/lib/radarr/init ]; then + curl -sf --retry 10 --retry-connrefused \ + -H "X-Api-Key: $RADARR_API_KEY" \ + "$RADARR_HOST/api/v1/health" + + if [ -f /etc/radarr/setup.sh ]; then + # shellcheck disable=SC1091 + . /etc/radarr/setup.sh + fi + + touch /var/lib/radarr/init +fi + +trap 'kill -INT "$PID"' INT TERM +wait "$PID" +exit $? diff --git a/packages/docker/sonarr/default.nix b/packages/docker/sonarr/default.nix new file mode 100644 index 0000000..854e8d2 --- /dev/null +++ b/packages/docker/sonarr/default.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: +let + entrypoint = pkgs.writeTextFile { + name = "entrypoint"; + executable = true; + destination = "/bin/entrypoint"; + text = builtins.readFile ./entrypoint.sh; + }; +in +pkgs.dockerTools.buildImage { + name = "sonarr"; + fromImage = import ../base { inherit pkgs; }; + + copyToRoot = pkgs.buildEnv { + name = "root"; + paths = with pkgs; [ + entrypoint + sonarr + xmlstarlet + curl + jq + ]; + pathsToLink = [ + "/bin" + "/lib" + ]; + }; + + runAsRoot = '' + ${pkgs.dockerTools.shadowSetup} + ''; + + config = { + Entrypoint = [ "entrypoint" ]; + ExposedPorts = { + "8989/tcp" = { }; + }; + WorkingDir = "/var/lib/sonarr"; + Volumes = { + "/var/lib/sonarr" = { }; + }; + }; +} diff --git a/packages/docker/sonarr/entrypoint.sh b/packages/docker/sonarr/entrypoint.sh new file mode 100644 index 0000000..86f0bad --- /dev/null +++ b/packages/docker/sonarr/entrypoint.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env sh + +set -o errexit +set -o nounset + +if [ ! -f /var/lib/sonarr/init ]; then + echo '' > /var/lib/sonarr/config.xml + + xmlstarlet ed -L \ + -s /Config -t elem -n LaunchBrowser -v "False" \ + -s /Config -t elem -n ApiKey -v "$SONARR_API_KEY" \ + -s /Config -t elem -n AuthenticationMethod -v "External" \ + -s /Config -t elem -n AuthenticationRequired -v "DisabledForLocalAddresses" \ + -s /Config -t elem -n LogLevel -v "info" \ + -s /Config -t elem -n UrlBase -v "${SONARR_URL_BASE:-}" \ + -s /Config -t elem -n InstanceName -v "${SONARR_INSTANCE_NAME:-sonarr}" \ + -s /Config -t elem -n AnalyticsEnabled -v "False" \ + /var/lib/sonarr/config.xml +fi + +Sonarr -data=/var/lib/sonarr -nobrowser "$@" & +PID=$! + +SONARR_HOST="http://localhost:8989${SONARR_URL_BASE:-}" + +if [ ! -f /var/lib/sonarr/init ]; then + curl -sf --retry 10 --retry-connrefused \ + -H "X-Api-Key: $SONARR_API_KEY" \ + "$SONARR_HOST/api/v1/health" + + if [ -f /etc/sonarr/setup.sh ]; then + # shellcheck disable=SC1091 + . /etc/sonarr/setup.sh + fi + + touch /var/lib/sonarr/init +fi + +trap 'kill -INT "$PID"' INT TERM +wait "$PID" +exit $?