diff --git a/machines/deedee/configuration.nix b/machines/deedee/configuration.nix index e1d9fb5..bd3520f 100644 --- a/machines/deedee/configuration.nix +++ b/machines/deedee/configuration.nix @@ -1,8 +1,10 @@ _: let mediaPath = "/mnt/media"; - videoPath = "${mediaPath}/video"; + audiobooksPath = "${mediaPath}/audiobooks"; + podcastsPath = "${mediaPath}/podcasts"; torrentsPath = "${mediaPath}/torrents"; + videoPath = "${mediaPath}/video"; in rec { sops = { @@ -166,6 +168,10 @@ rec { }; # containers + audiobookshelf = { + inherit audiobooksPath podcastsPath; + enable = true; + }; authelia.enable = true; bazarr = { inherit videoPath; diff --git a/machines/deedee/secrets.sops.yaml b/machines/deedee/secrets.sops.yaml index 62a81d3..f6371ab 100644 --- a/machines/deedee/secrets.sops.yaml +++ b/machines/deedee/secrets.sops.yaml @@ -20,6 +20,10 @@ credentials: ajgon: ENC[AES256_GCM,data:oLXu3WTptpFJIT2pzNGvsjEkbbBXCfW7hPf2gOkfOXcipRdUQNAurAjj0kvjhDpzR3u3UtFnOIRQLiDUYyG34yX7tYEO3fKnwg==,iv:yLuRuigc0WxiAPhoIj1W5+kZ/v6y/IThivWgd7WgBx0=,tag:0sv25F9uCmZABxiBjP3aaw==,type:str] system: apps: + audiobookshelf: + env: + OIDC_SECRET_ENCRYPTED: ENC[AES256_GCM,data:KWh3ZPiqSvoLSjONdQCwQqr8+ygw0pbyCyy210JWZJ66YT5bTjG2le+PBYpaTQOO1VTnzBh4uV4/xbkFdeWWmD12SUuha2h0gdct/CYviW5zVQ6bjS6EDk9mVvFcs0VkTLLGInrEYqtf06EmYNRnedgEAICvaKqN5sBAYOQ2qBWXutU=,iv:VKI246I8itOahs2gqDWONbg2NnL7Wn5N0TAOPSDez/g=,tag:kON5jjmpbygqw0SV76xX6w==,type:str] + OIDC_SECRET_RAW: ENC[AES256_GCM,data:af1X0LIiN2MqAtKLKCkPWRK0I4yZ3RTyK8uKoL+VIQroiuMwrZufU+l6es6+DyWyJDaYBgOmML895LrTA17OJcOaxkOGTfY1,iv:JJXIEk1zJEEQ0uHM2Da4c6q8WPNHiev7aM5VIQT2njM=,tag:8cD6OlMhruZGJ0aGEZILZw==,type:str] authelia: env: AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET: ENC[AES256_GCM,data:KBTMgh3kE2xhAirF8TtZIrNgP418zZDQj4JJ4rF2t+0Rj3XzdE7pzE4ZO3LC0tuLjrVJNVdoQrBl7bv1OH8hPA==,iv:y6Ri1xrTg5b+d+TbIYTzSILzujHT8BhFl3gHCOjHUA0=,tag:AWrPQ6DdhXypNvVW9roP5w==,type:str] @@ -150,8 +154,8 @@ sops: c3FoaFNzbjJubzlBckdDb2lNOUZtOGMKRbHxa1B3QAdredBMTd7W7g3kRz6l8uyV bBclsA8Gm7p+6ndV39sN+Daqm5MyggY1Prwv/Ukdd5Q+1C+XsEW6OQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-10-31T23:47:11Z" - mac: ENC[AES256_GCM,data:RTxJ2xtfJscNo3vDwSA+tSyAQmOhY5fnW9Yz/bTy+XyPVaUGYzcrLMqrzYobFbeFDIi+lUF+b7HLOWvi4d8IDOb33c00QnFNbqimLoQJjJBLI52g/FquZC3gsYpqo8yqOi2IyBXF3gVni8Ij+XJl2TcLo5mRI43OuuAXhsH6aiM=,iv:QS6a5fjqjFRST97hUPjcgWmZxVSXHrGtzeRbP2jbHDM=,tag:rpkWZAjAos0gbFRg5lCtIg==,type:str] + lastmodified: "2024-11-01T16:15:00Z" + mac: ENC[AES256_GCM,data:Z88ZU/SgwuH0xe9yiZZeuxQeyoaW7CVEawIx6SrB+Py0rt/HgnomN86qC/lzBl+H9Qgc0d4EFymv+pR5YYVVpxLuJPce3OJe+bzg9HZ3xPMxjsoG4WTVQzW5DSgx6+hWjsFk7m0a/AjqSClMncorVXcc6+RcAJ1NXkjfVy4SvLg=,iv:lQICt+VCx24P5bL+EnhSY+j41ffL3sKhK3FnHS7/Tdw=,tag:5x2YA/9Kx7PtI9Wkm51RXQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 diff --git a/modules/system/containers/audiobookshelf/default.nix b/modules/system/containers/audiobookshelf/default.nix new file mode 100644 index 0000000..258d1e1 --- /dev/null +++ b/modules/system/containers/audiobookshelf/default.nix @@ -0,0 +1,116 @@ +{ + config, + lib, + pkgs, + svc, + ... +}: +let + cfg = config.mySystemApps.audiobookshelf; +in +{ + options.mySystemApps.audiobookshelf = { + enable = lib.mkEnableOption "audiobookshelf container"; + backup = lib.mkEnableOption "data backup" // { + default = true; + }; + dataDir = lib.mkOption { + type = lib.types.str; + description = "Path to directory containing data."; + default = "/var/lib/audiobookshelf"; + }; + audiobooksPath = lib.mkOption { + type = lib.types.str; + description = "Path to directory containing audiobooks."; + }; + podcastsPath = lib.mkOption { + type = lib.types.str; + description = "Path to directory containing podcasts."; + }; + }; + + config = lib.mkIf cfg.enable { + warnings = [ (lib.mkIf (!cfg.backup) "WARNING: Backups for audiobookshelf are disabled!") ]; + + virtualisation.oci-containers.containers.audiobookshelf = svc.mkContainer { + cfg = { + image = "ghcr.io/advplyr/audiobookshelf:2.15.1@sha256:9096480cb2b8cbfb3da155ea3cea5e9bfd4f3c2aae6196225c5b26d31bad1a99"; + user = "65000:65000"; + environment = { + PORT = "3000"; + }; + volumes = [ + "${cfg.dataDir}/config:/config" + "${cfg.audiobooksPath}:/audiobooks" + "${cfg.podcastsPath}:/podcasts" + "/var/cache/audiobookshelf/metadata:/metadata" + ]; + }; + opts = { + # for fetching metadata + allowPublic = true; + }; + }; + + mySystemApps.authelia.oidcClients = [ + { + client_id = "audiobookshelf"; + client_name = "audiobookshelf"; + client_secret = "$pbkdf2-sha512$310000$COYPbh8tgyObJW6Dvqgm0w$MyA1TlJgfKGBOJRs/edyTdLgxXsI6yU8KbwNx06Gow95lK4KofkLRtVV5s3EYU6DtlqUJCNdsjjZYL4DstvHiw"; # unencrypted version in SOPS + consent_mode = "implicit"; + public = false; + authorization_policy = "two_factor"; + require_pkce = true; + pkce_challenge_method = "S256"; + redirect_uris = [ + "https://audiobookshelf.${config.mySystem.rootDomain}/auth/openid/callback" + "https://audiobookshelf.${config.mySystem.rootDomain}/auth/openid/mobile-redirect" + ]; + scopes = [ + "email" + "openid" + "profile" + "groups" + ]; + userinfo_signed_response_alg = "none"; + token_endpoint_auth_method = "client_secret_basic"; + } + ]; + + services = { + nginx.virtualHosts.audiobookshelf = svc.mkNginxVHost { + host = "audiobookshelf"; + proxyPass = "http://audiobookshelf.docker:3000"; + autheliaIgnorePaths = [ + "/api" + "/login" + "/status" + ]; + customCSP = '' + default-src 'self' 'unsafe-eval' 'wasm-unsafe-eval' 'unsafe-inline' data: + mediastream: blob: wss: https://*.${config.mySystem.rootDomain}; + object-src 'none'; + img-src 'self' data: blob: https:; + ''; + }; + restic.backups = lib.mkIf cfg.backup ( + svc.mkRestic { + name = "audiobookshelf"; + paths = [ cfg.dataDir ]; + } + ); + }; + + systemd.services.docker-audiobookshelf = { + path = [ pkgs.iproute2 ]; + preStart = lib.mkAfter '' + mkdir -p "${cfg.dataDir}/config" /var/cache/audiobookshelf/metadata + chown 65000:65000 "${cfg.dataDir}/config" /var/cache/audiobookshelf/metadata + ''; + }; + + environment.persistence."${config.mySystem.impermanence.persistPath}" = + lib.mkIf config.mySystem.impermanence.enable + { directories = [ cfg.dataDir ]; }; + }; +} diff --git a/modules/system/containers/default.nix b/modules/system/containers/default.nix index cd70ab2..920ffaf 100644 --- a/modules/system/containers/default.nix +++ b/modules/system/containers/default.nix @@ -1,5 +1,6 @@ _: { imports = [ + ./audiobookshelf ./authelia ./bazarr ./coredns