diff --git a/WORKAROUNDS.md b/WORKAROUNDS.md index d220cd8..341ad91 100644 --- a/WORKAROUNDS.md +++ b/WORKAROUNDS.md @@ -348,7 +348,7 @@ These are not workarounds but known incomplete configurations: | `systems/x86_64-linux/jallen-nas/apps.nix` | 47 | Authentik environment secrets file not wired up | | `modules/nixos/services/sparky-fitness/default.nix` | — | ~~DB passwords not yet moved to SOPS~~ — resolved; secrets now via `mkSopsEnvFile`; run `sops secrets/nas-secrets.yaml` to add real values for `jallen-nas/sparky-fitness/{db-password,api-encryption-key,auth-secret}` | | `modules/nixos/services/your-spotify/default.nix` | 36 | Spotify API keys not yet moved to SOPS | -| `modules/nixos/services/booklore/default.nix` | 25 | Database password not yet a SOPS secret | +| `modules/nixos/services/booklore/default.nix` | 28 | Database password not yet a SOPS secret | | `packages/raspberrypi/udev-rules/default.nix` | 33 | `15-i2c-modprobe.rules` disabled; `i2cprobe` script not ported | | `modules/nixos/homeassistant/services/homeassistant/default.nix` | 214 | `roborock` integration marked broken | diff --git a/modules/nixos/services/ai/default.nix b/modules/nixos/services/ai/default.nix index c100d27..0b4646b 100755 --- a/modules/nixos/services/ai/default.nix +++ b/modules/nixos/services/ai/default.nix @@ -51,7 +51,7 @@ let port = 8127; host = "0.0.0.0"; openFirewall = cfg.openFirewall; - model = "${cfg.configDir}/llama-cpp/models/${cfg.llama-cpp.model}.gguf"; + model = null; package = pkgs.llama-cpp-rocm; extraFlags = [ "--fit" diff --git a/modules/nixos/services/booklore/default.nix b/modules/nixos/services/grimmory/default.nix similarity index 50% rename from modules/nixos/services/booklore/default.nix rename to modules/nixos/services/grimmory/default.nix index c764e6a..76aea76 100644 --- a/modules/nixos/services/booklore/default.nix +++ b/modules/nixos/services/grimmory/default.nix @@ -5,24 +5,26 @@ ... }: let - cfg = config.${namespace}.services.booklore; + cfg = config.${namespace}.services.grimmory; in { imports = [ (lib.${namespace}.mkContainerService { inherit config; - name = "booklore"; - image = "booklore/booklore"; + name = "grimmory"; + image = "ghcr.io/grimmory-tools/grimmory"; internalPort = 6060; volumes = [ - "${cfg.configDir}/booklore:/app/data" + "${cfg.configDir}/grimmory:/app/data" "${cfg.configDir}/bookdrop:/bookdrop" "${cfg.dataDir}/books:/books" ]; environment = { - DATABASE_URL = "jdbc:mariadb://10.0.1.3:3306/booklore"; - DATABASE_USERNAME = "booklore"; - # TODO: move DATABASE_PASSWORD to a sops secret + USER_ID = "1000"; + GROUP_ID = "1000"; + TZ = "UTC"; + DATABASE_URL = "jdbc:mariadb://10.0.1.3:3306/grimmory"; + DATABASE_USERNAME = "grimmory"; DATABASE_PASSWORD = "Lucifer008!"; }; }) diff --git a/modules/nixos/services/kavita/default.nix b/modules/nixos/services/kavita/default.nix new file mode 100644 index 0000000..ed9e340 --- /dev/null +++ b/modules/nixos/services/kavita/default.nix @@ -0,0 +1,41 @@ +{ + config, + lib, + namespace, + ... +}: +with lib; +let + name = "kavita"; + cfg = config.${namespace}.services.${name}; + rootUrl = "https://kavita.${namespace}.dev/"; + + kavitaConfig = lib.${namespace}.mkModule { + inherit config name; + description = "kavita"; + options = { }; + moduleConfig = { + sops = { + secrets = { + "jallen-nas/kavita/token" = { + sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml"); + owner = config.users.users.kavita.name; + group = config.users.users.kavita.group; + restartUnits = [ "kavita.service" ]; + }; + }; + }; + services.kavita = { + enable = true; + dataDir = "${cfg.configDir}/kavita"; + tokenKeyFile = config.sops.secrets."jallen-nas/kavita/token".path; + settings = { + Port = cfg.port; + }; + }; + }; + }; +in +{ + imports = [ kavitaConfig ]; +} diff --git a/modules/nixos/services/lemonade/default.nix b/modules/nixos/services/lemonade/default.nix index 0082805..fef1a7c 100644 --- a/modules/nixos/services/lemonade/default.nix +++ b/modules/nixos/services/lemonade/default.nix @@ -34,7 +34,7 @@ let # Override mkModule's default port of 80 with lemonade's actual default. port = mkOpt lib.types.int 8000 "Port lemonade-router listens on"; - host = mkOpt lib.types.str "127.0.0.1" "Address lemonade-router binds to"; + host = mkOpt lib.types.str "0.0.0.0" "Address lemonade-router binds to"; logLevel = mkOpt (lib.types.enum [ "critical" diff --git a/secrets/nas-secrets.yaml b/secrets/nas-secrets.yaml index aad98bb..407f95d 100644 --- a/secrets/nas-secrets.yaml +++ b/secrets/nas-secrets.yaml @@ -96,6 +96,8 @@ jallen-nas: auth-secret: ENC[AES256_GCM,data:aJIjDzyJy3nWUNpKHEGyYdTfO93pfNcLKTTz6lKl8IO49JHuzFefaCNCzbwSKVMda8snohE2DE9Ul94paIcSwQ==,iv:rMZVu1SACErvtrhlLecP1bQ/2wnvZ1UnlYHMqFbB8I4=,tag:IxEw+MvDqAmK492uiIIRaw==,type:str] grafana: secret-key: ENC[AES256_GCM,data:dPHXEAKGrbbM36uH3W4yzm3GmJI=,iv:yHMAMJ8w+uoH/IvLSbxyQm6dEml0MWvwfRIIVHmc6LE=,tag:AyDLS20gUH4gupRGrtGReQ==,type:str] + kavita: + token: ENC[AES256_GCM,data:XurnehEZ/jCn+lxtTyty3WkDb17nQ7X3dIIys8O1l17gNzBMyqCLuzQaKLvqAV13PIaGBRTSnlNe7hDs5XYsI2nyL/l0ptPPXgKGEujEtTL8ei0rxTAYnA==,iv:Guinyj+EQNSUE+z+yu3HTF+leoxk7LWXBX/HGcLEki4=,tag:hfkgnjFAwUEVXtDT5HFJTg==,type:str] sops: shamir_threshold: 1 age: @@ -243,8 +245,8 @@ sops: L0gwQm5takNjMkVGNzVlSStJYlUwWDAKP8QA3rRUHYbyyhPC/k0Eq2EIKfjyc7Co 7BkHH3msC6h9g42BB5iIYe6KQ+UGxMQBFvp+qSB27jaIfajN5MP0BA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-24T19:34:00Z" - mac: ENC[AES256_GCM,data:vuAtq87oIAIbWw7d/PwNPfVIlWJx3C1sT5tlpgLvHTgCAp8ZtSSBhqTJNCV7za+kjrF/SrZ0Asc1Ui6W3spgU6QAu2TR7JtAseXDyN7c8hLbBzZdZ5RtrqYdr8bj+dohbC9ZTHBt1YH7iXb1rm3CmwkCkzSY6ux3afnWubK2TIg=,iv:UAnH3J0Lnyxk1XPk3Zlm/VpCSA7omv9czc50C9qrfsM=,tag:Xh+iUD9S2rSlpmUoa5uQ8A==,type:str] + lastmodified: "2026-03-30T01:56:41Z" + mac: ENC[AES256_GCM,data:U7xBMz0kJd2fF81rCRD0x4g573lEUnn2Q8e6V/0zgwzoaC39VyZ3RBAUVBS+5d4GSTjrU82sucSNYBZphOGODdgnmL7jSBwaKxg4co9fjuABFmn5WFKJgsw07F48/F2DraftSlRoq1YYkzOhiravgVyWU6aC7o5av+nFVhhfcrM=,iv:bnGpEY6mjPrmeJ+bQdZkXQPTzkBxmIy+5B8/dtJDLmM=,tag:OqvH+y5vjQryzyMUof4isA==,type:str] pgp: - created_at: "2026-02-06T15:34:30Z" enc: |- @@ -267,4 +269,4 @@ sops: -----END PGP MESSAGE----- fp: CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684 unencrypted_suffix: _unencrypted - version: 3.12.1 + version: 3.12.2 diff --git a/systems/x86_64-linux/jallen-nas/apps.nix b/systems/x86_64-linux/jallen-nas/apps.nix index f3ce6aa..9b7b8c9 100755 --- a/systems/x86_64-linux/jallen-nas/apps.nix +++ b/systems/x86_64-linux/jallen-nas/apps.nix @@ -46,10 +46,6 @@ in port = 4823; # environmentFile = "/run/secrets/jallen-nas/authentik-env"; # TODO }; - booklore = { - enable = false; - port = 6066; - }; caddy = enabled; cockpit = { enable = true; @@ -122,6 +118,10 @@ in port = 61208; createUser = true; }; + grimmory = { + enable = false; + port = 6066; + }; headscale = { enable = false; port = 2112; @@ -132,12 +132,6 @@ in port = 2283; reverseProxy = enabled; }; - lemonade = { - enable = true; - port = 8001; - modelsDir = "/media/nas/main/ai/lemonade/models"; - reverseProxy = disabled; - }; jellyfin = { enable = true; port = 8096; @@ -149,6 +143,17 @@ in createUser = true; reverseProxy = enabled; }; + kavita = { + enable = true; + port = 5000; + reverseProxy = disabled; + }; + lemonade = { + enable = true; + port = 8001; + modelsDir = "/media/nas/main/ai/lemonade/models"; + reverseProxy = disabled; + }; lubelogger = { enable = true; port = 6754; diff --git a/systems/x86_64-linux/jallen-nas/nas-defaults.nix b/systems/x86_64-linux/jallen-nas/nas-defaults.nix index 1f2c314..4031c2d 100644 --- a/systems/x86_64-linux/jallen-nas/nas-defaults.nix +++ b/systems/x86_64-linux/jallen-nas/nas-defaults.nix @@ -38,7 +38,6 @@ in "attic" "authentik" "authentikRac" - "booklore" "caddy" "calibre" "calibre-web" @@ -53,11 +52,13 @@ in "glances" "grafana" "guacd" + "grimmory" "headscale" "immich" "jellyfin" - "lemonade" "jellyseerr" + "kavita" + "lemonade" "lubelogger" "manyfold" "matrix" diff --git a/systems/x86_64-linux/jallen-nas/services.nix b/systems/x86_64-linux/jallen-nas/services.nix index 79ff22e..e2100ed 100755 --- a/systems/x86_64-linux/jallen-nas/services.nix +++ b/systems/x86_64-linux/jallen-nas/services.nix @@ -144,12 +144,12 @@ in }; initialDatabases = [ { - name = "booklore"; + name = "grimmory"; } ]; ensureUsers = [ { - name = "booklore"; + name = "grimmory"; ensurePermissions = { "database.*" = "ALL PRIVILEGES"; "*.*" = "SELECT, LOCK TABLES";