From b69ff8e50d5edf7623529a219eff3286e61dc8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Schwarz=C3=A4ugl?= Date: Mon, 16 Jun 2025 23:02:57 +0200 Subject: [PATCH] chore: general cleanup --- SwarselSystems.org | 161 +++-- hosts/nixos/moonside/default.nix | 10 - index.html | 937 +++++++++++++------------ modules/nixos/server/immich.nix | 2 +- modules/nixos/server/kavita.nix | 1 + modules/nixos/server/matrix.nix | 19 +- modules/nixos/server/navidrome.nix | 4 +- modules/nixos/server/nextcloud.nix | 2 +- modules/nixos/server/nginx.nix | 2 - modules/nixos/server/postgresql.nix | 17 + modules/nixos/server/restic.nix | 1 - modules/nixos/server/syncthing.nix | 22 +- modules/nixos/server/transmission.nix | 78 +- profiles/nixos/localserver/default.nix | 1 + 14 files changed, 709 insertions(+), 548 deletions(-) create mode 100644 modules/nixos/server/postgresql.nix diff --git a/SwarselSystems.org b/SwarselSystems.org index 7cb75f8..77185f7 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -1623,16 +1623,6 @@ This machine mainly acts as an external sync helper. It manages the following th devices = [ "winters" "magicant" "${workHostName}" ]; id = "hgp9s-fyq3p"; }; - ".elfeed" = { - path = "/sync/elfeed"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "winters" ]; - id = "h7xbs-fs9v1"; - }; "Documents" = { path = "/sync/Documents"; type = "receiveonly"; @@ -4685,6 +4675,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a navidrome = lib.mkDefault true; spotifyd = lib.mkDefault true; mpd = lib.mkDefault true; + postgresql = lib.mkDefault true; matrix = lib.mkDefault true; nextcloud = lib.mkDefault true; immich = lib.mkDefault true; @@ -7722,8 +7713,6 @@ Here we just define some aliases for rebuilding the system, and we allow some in lego ]; - # users.users.acme = {}; - sops = { # secrets.dnstokenfull = { owner = "acme"; }; secrets.dnstokenfull = { }; @@ -7836,6 +7825,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t user = serviceUser; settings.Port = servicePort; tokenKeyFile = config.sops.secrets.kavita.path; + dataDir = "/Vault/data/kavita"; }; nodes.moonside.services.nginx = { @@ -7960,7 +7950,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t users = { groups = { - "$(serviceGroup}" = { + "${serviceGroup}" = { gid = 61593; }; }; @@ -7990,6 +7980,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t Port = servicePort; MusicFolder = "/Vault/Eternor/Music"; PlaylistsPath = "./Playlists"; + AutoImportPlaylists = false; EnableSharing = true; EnableTranscodingConfig = true; Scanner.GroupAlbumReleases = true; @@ -8016,6 +8007,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png"; UIWelcomeMessage = "~SwarselSound~"; + EnableInsightsCollector = false; }; }; @@ -8218,13 +8210,35 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t } #+end_src +**** postgresql + +#+begin_src nix :tangle modules/nixos/server/postgresql.nix + { config, lib, pkgs, ... }: + let + serviceName = "postgresql"; + postgresVersion = 14; + in + { + options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server"; + config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" { + services = { + postgresql = { + enable = true; + package = pkgs."postgresql_${builtins.toString postgresVersion}"; + dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}"; + }; + }; + }; + } +#+end_src + **** matrix :PROPERTIES: :CUSTOM_ID: h:1e68d84a-8f99-422f-89ac-78f664ac0013 :END: #+begin_src nix :tangle modules/nixos/server/matrix.nix - { config, lib, pkgs, sops, ... }: + { lib, config, pkgs, ... }: let matrixDomain = "swatrix.swarsel.win"; serviceName = "matrix"; @@ -8342,12 +8356,16 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t matrix-synapse = { enable = true; + dataDir = "/Vault/data/matrix-synapse"; settings = { - app_service_config_files = [ - "/var/lib/matrix-synapse/telegram-registration.yaml" - "/var/lib/matrix-synapse/whatsapp-registration.yaml" - "/var/lib/matrix-synapse/signal-registration.yaml" - "/var/lib/matrix-synapse/doublepuppet.yaml" + app_service_config_files = let + inherit (config.services.matrix-synapse) dataDir; + in + [ + "${dataDir}/telegram-registration.yaml" + "${dataDir}/whatsapp-registration.yaml" + "${dataDir}/signal-registration.yaml" + "${dataDir}/doublepuppet.yaml" ]; server_name = matrixDomain; public_baseurl = "https://${matrixDomain}"; @@ -8602,7 +8620,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; package = pkgs.nextcloud31; hostName = serviceDomain; - home = "/Vault/apps/nextcloud"; + home = "/Vault/data/nextcloud"; datadir = "/Vault/data/nextcloud"; https = true; configureRedis = true; @@ -8672,7 +8690,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t host = "0.0.0.0"; port = servicePort; openFirewall = true; - mediaLocation = "/Vault/Eternor/Immich"; + mediaLocation = "/Vault/Eternor/Immich"; # dataDir environment = { IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003"; }; @@ -8866,6 +8884,21 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= { self, pkgs, lib, config, ... }: let serviceDomain = "store.swarsel.win"; + lidarrUser = "lidarr"; + lidarrGroup = lidarrUser; + lidarrPort = 8686; + radarrUser = "radarr"; + radarrGroup = radarrUser; + radarrPort = 7878; + sonarrUser = "sonarr"; + sonarrGroup = sonarrUser; + sonarrPort = 8989; + readarrUser = "readarr"; + readarrGroup = readarrUser; + readarrPort = 8787; + prowlarrUser = "prowlarr"; + prowlarrGroup = prowlarrUser; + prowlarrPort = 9696; in { options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server"; @@ -8877,11 +8910,11 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= dockeruser = { gid = 1155; }; - radarr = { }; - readarr = { }; - sonarr = { }; - lidarr = { }; - prowlarr = { }; + "${radarrGroup}" = { }; + "${readarrGroup}" = { }; + "${sonarrGroup}" = { }; + "${lidarrGroup}" = { }; + "${prowlarrGroup}" = { }; }; users = { dockeruser = { @@ -8890,29 +8923,29 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= group = "docker"; extraGroups = [ "users" ]; }; - radarr = { + "${radarrUser}" = { isSystemUser = true; - group = "radarr"; + group = radarrGroup; extraGroups = [ "users" ]; }; - readarr = { + "${readarrGroup}" = { isSystemUser = true; - group = "readarr"; + group = readarrGroup; extraGroups = [ "users" ]; }; - sonarr = { + "${sonarrGroup}" = { isSystemUser = true; - group = "sonarr"; + group = sonarrGroup; extraGroups = [ "users" ]; }; - lidarr = { + "${lidarrUser}" = { isSystemUser = true; - group = "lidarr"; + group = lidarrGroup; extraGroups = [ "users" ]; }; - prowlarr = { + "${prowlarrGroup}" = { isSystemUser = true; - group = "prowlarr"; + group = prowlarrGroup; extraGroups = [ "users" ]; }; }; @@ -8938,32 +8971,45 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= services = { radarr = { enable = true; + user = radarrUser; + group = radarrGroup; + settings.server.port = radarrPort; openFirewall = true; - dataDir = "/Vault/apps/radarr"; + dataDir = "/Vault/data/radarr"; }; readarr = { enable = true; + user = readarrUser; + group = readarrGroup; + settings.server.port = readarrPort; openFirewall = true; - dataDir = "/Vault/apps/readarr"; + dataDir = "/Vault/data/readarr"; }; sonarr = { enable = true; + user = sonarrUser; + group = sonarrGroup; + settings.server.port = sonarrPort; openFirewall = true; - dataDir = "/Vault/apps/sonarr"; + dataDir = "/Vault/data/sonarr"; }; lidarr = { enable = true; + user = lidarrUser; + group = lidarrGroup; + settings.server.port = lidarrPort; openFirewall = true; - dataDir = "/Vault/apps/lidarr"; + dataDir = "/Vault/data/lidarr"; }; prowlarr = { enable = true; + settings.server.port = prowlarrPort; openFirewall = true; }; nginx = { virtualHosts = { - "store.swarsel.win" = { + "${serviceDomain}" = { enableACME = false; forceSSL = false; acmeRoot = null; @@ -8975,31 +9021,31 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= ''; }; "/radarr" = { - proxyPass = "http://localhost:7878"; + proxyPass = "http://localhost:${builtins.toString radarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/readarr" = { - proxyPass = "http://localhost:8787"; + proxyPass = "http://localhost:${builtins.toString readarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/sonarr" = { - proxyPass = "http://localhost:8989"; + proxyPass = "http://localhost:${builtins.toString sonarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/lidarr" = { - proxyPass = "http://localhost:8686"; + proxyPass = "http://localhost:${builtins.toString lidarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/prowlarr" = { - proxyPass = "http://localhost:9696"; + proxyPass = "http://localhost:${builtins.toString prowlarrPort}"; extraConfig = '' client_max_body_size 0; ''; @@ -9048,7 +9094,7 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= user = serviceUser; group = serviceGroup; dataDir = "/Vault/data/syncthing"; - configDir = "/Vault/apps/syncthing"; + configDir = "/Vault/data/syncthing/.config/syncthing"; guiAddress = "0.0.0.0:${builtins.toString servicePort}"; openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery relay.enable = false; @@ -9106,16 +9152,16 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ]; id = "hgp9s-fyq3p"; }; - "Documents" = { - path = "/Vault/data/syncthing/Documents"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; - id = "hgr3d-pfu3w"; - }; + # "Documents" = { + # path = "/Vault/data/syncthing/Documents"; + # type = "receiveonly"; + # versioning = { + # type = "simple"; + # params.keep = "5"; + # }; + # devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; + # id = "hgr3d-pfu3w"; + # }; }; }; }; @@ -9188,7 +9234,6 @@ This manages backups for my pictures and obsidian files. "/Vault/Eternor/Paperless" "/Vault/Eternor/Bilder" "/Vault/Eternor/Immich" - "/Vault/familymedia" ]; pruneOpts = [ "--keep-daily 3" diff --git a/hosts/nixos/moonside/default.nix b/hosts/nixos/moonside/default.nix index 0a49c9c..dd7a28f 100644 --- a/hosts/nixos/moonside/default.nix +++ b/hosts/nixos/moonside/default.nix @@ -167,16 +167,6 @@ in devices = [ "winters" "magicant" "${workHostName}" ]; id = "hgp9s-fyq3p"; }; - ".elfeed" = { - path = "/sync/elfeed"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "winters" ]; - id = "h7xbs-fs9v1"; - }; "Documents" = { path = "/sync/Documents"; type = "receiveonly"; diff --git a/index.html b/index.html index 057b9da..7587754 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + SwarselSystems: NixOS + Emacs Configuration @@ -249,10 +249,10 @@
  • 3.1.3. Virtual hosts @@ -312,8 +312,8 @@
  • 3.2.1.27. fhs
  • 3.2.1.28. swarsel-displaypower
  • 3.2.1.29. swarsel-mgba
  • -
  • 3.2.1.30. swarsel-deploy
  • -
  • 3.2.1.31. sshrm
  • +
  • 3.2.1.30. swarsel-deploy
  • +
  • 3.2.1.31. sshrm
  • 3.2.2. Overlays (additions, overrides, nixpkgs-stable)
  • @@ -321,39 +321,39 @@
  • 3.2.4. Library functions
  • -
  • 3.2.5. Auxiliary files +
  • 3.2.5. Auxiliary files
  • @@ -365,7 +365,7 @@
  • 3.3.1.1. Imports, non-server settings
  • 3.3.1.2. Shared Configuration Options
  • 3.3.1.3. General NixOS settings (stateVersion)
  • -
  • 3.3.1.4. Share configuration between nodes
  • +
  • 3.3.1.4. Share configuration between nodes
  • 3.3.1.5. System Packages
  • 3.3.1.6. Setup home-manager base
  • 3.3.1.7. Setup home-manager specialArgs
  • @@ -379,10 +379,10 @@
  • 3.3.1.15. Pipewire
  • 3.3.1.16. Common network settings
  • 3.3.1.17. Time, locale settings
  • -
  • 3.3.1.18. Meta options
  • -
  • 3.3.1.19. Topology
  • +
  • 3.3.1.18. Meta options
  • +
  • 3.3.1.19. Topology
  • 3.3.1.20. sops
  • -
  • 3.3.1.21. PII management
  • +
  • 3.3.1.21. PII management
  • 3.3.1.22. Theme (stylix)
  • 3.3.1.23. Programs (including zsh setup)
  • 3.3.1.25. Hardware compatibility settings (Yubikey, Ledger, Keyboards) - udev rules @@ -436,23 +436,24 @@
  • 3.3.2.11. spotifyd
  • 3.3.2.12. mpd
  • 3.3.2.13. pipewire
  • -
  • 3.3.2.14. matrix
  • -
  • 3.3.2.15. nextcloud
  • -
  • 3.3.2.16. immich
  • -
  • 3.3.2.17. paperless (tika, gotenberg)
  • -
  • 3.3.2.18. transmission
  • -
  • 3.3.2.19. syncthing
  • -
  • 3.3.2.20. restic
  • -
  • 3.3.2.21. monitoring (Grafana)
  • -
  • 3.3.2.22. Jenkins
  • -
  • 3.3.2.23. Emacs elfeed (RSS Server)
  • -
  • 3.3.2.24. FreshRSS
  • -
  • 3.3.2.25. forgejo (git server)
  • -
  • 3.3.2.26. Anki Sync Server
  • -
  • 3.3.2.27. kanidm
  • -
  • 3.3.2.28. oauth2-proxy
  • -
  • 3.3.2.29. Firefly-III
  • -
  • 3.3.2.30. Koillection
  • +
  • 3.3.2.14. postgresql
  • +
  • 3.3.2.15. matrix
  • +
  • 3.3.2.16. nextcloud
  • +
  • 3.3.2.17. immich
  • +
  • 3.3.2.18. paperless (tika, gotenberg)
  • +
  • 3.3.2.19. transmission
  • +
  • 3.3.2.20. syncthing
  • +
  • 3.3.2.21. restic
  • +
  • 3.3.2.22. monitoring (Grafana)
  • +
  • 3.3.2.23. Jenkins
  • +
  • 3.3.2.24. Emacs elfeed (RSS Server)
  • +
  • 3.3.2.25. FreshRSS
  • +
  • 3.3.2.26. forgejo (git server)
  • +
  • 3.3.2.27. Anki Sync Server
  • +
  • 3.3.2.28. kanidm
  • +
  • 3.3.2.29. oauth2-proxy
  • +
  • 3.3.2.30. Firefly-III
  • +
  • 3.3.2.31. Koillection
  • 3.3.3. Darwin @@ -467,11 +468,11 @@
  • 3.3.4.3. VmWare
  • 3.3.4.4. Auto-login
  • 3.3.4.5. nswitch-rcm
  • -
  • 3.3.4.6. Framework
  • -
  • 3.3.4.7. AMD CPU
  • -
  • 3.3.4.8. AMD GPU
  • -
  • 3.3.4.9. Hibernation
  • -
  • 3.3.4.10. BTRFS
  • +
  • 3.3.4.6. Framework
  • +
  • 3.3.4.7. AMD CPU
  • +
  • 3.3.4.8. AMD GPU
  • +
  • 3.3.4.9. Hibernation
  • +
  • 3.3.4.10. BTRFS
  • 3.3.4.11. work
  • 3.3.4.12. Minimal Install
  • @@ -520,7 +521,7 @@
  • 3.4.1.29.1. gnome-keyring
  • 3.4.1.29.2. KDE Connect
  • 3.4.1.29.3. Mako
  • -
  • 3.4.1.29.4. SwayOSD
  • +
  • 3.4.1.29.4. SwayOSD
  • 3.4.1.29.5. yubikey-touch-detector
  • @@ -545,7 +546,7 @@ @@ -723,7 +724,7 @@ @@ -732,7 +733,7 @@

    -This file has 69596 words spanning 18782 lines and was last revised on 2025-06-16 00:41:03 +0200. +This file has 69694 words spanning 18853 lines and was last revised on 2025-06-16 23:03:27 +0200.

    @@ -785,7 +786,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry

    -My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-06-16 00:41:03 +0200) +My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-06-16 23:03:27 +0200)

    @@ -1821,6 +1822,7 @@ in swarselsystems = lib.recursiveUpdate { + info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM"; firewall = lib.mkForce true; wallpaper = self + /wallpaper/lenovowp.png; hasBluetooth = true; @@ -1844,7 +1846,6 @@ in # home.stateVersion = lib.mkForce "23.05"; swarselsystems = lib.recursiveUpdate { - info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM"; isLaptop = true; isNixos = true; isSecondaryGpu = true; @@ -2461,12 +2462,12 @@ in -
    -
    3.1.3.2. Moonside (OCI)
    +
    +
    3.1.3.2. Moonside (OCI)
    -
    -
    3.1.3.2.1. Main Configuration
    +
    +
    3.1.3.2.1. Main Configuration
    { lib, config, primaryUser, ... }:
    @@ -2638,16 +2639,6 @@ in
                 devices = [ "winters" "magicant" "${workHostName}" ];
                 id = "hgp9s-fyq3p";
               };
    -          ".elfeed" = {
    -            path = "/sync/elfeed";
    -            type = "receiveonly";
    -            versioning = {
    -              type = "simple";
    -              params.keep = "5";
    -            };
    -            devices = [ "winters" ];
    -            id = "h7xbs-fs9v1";
    -          };
               "Documents" = {
                 path = "/sync/Documents";
                 type = "receiveonly";
    @@ -2711,8 +2702,8 @@ in
     
    -
    -
    3.1.3.2.2. hardware-configuration
    +
    +
    3.1.3.2.2. hardware-configuration

    loader.grub = { @@ -3355,8 +3346,8 @@ This is just a demo host. It applies all the configuration found in the common p I also set the WLR_RENDERER_ALLOW_SOFTWARE=1 to allow this configuration to run in a virtualized environment. I also enable qemuGuest for a smoother experience when testing on QEMU.

    -
    -
    3.1.4.4.1. Main configuration
    +
    +
    3.1.4.4.1. Main configuration
    { self, inputs, config, pkgs, lib, primaryUser, ... }:
    @@ -3435,8 +3426,8 @@ in
     
    -
    -
    3.1.4.4.2. NixOS dummy options configuration
    +
    +
    3.1.4.4.2. NixOS dummy options configuration
    _:
    @@ -3446,8 +3437,8 @@ in
     
    -
    -
    3.1.4.4.3. home-manager dummy options configuration
    +
    +
    3.1.4.4.3. home-manager dummy options configuration
    _:
    @@ -5228,8 +5219,8 @@ appimageTools.wrapType2 {
     
    -
    -
    3.2.1.30. swarsel-deploy
    +
    +
    3.2.1.30. swarsel-deploy
    # heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
    @@ -5360,8 +5351,8 @@ writeShellApplication {
     
    -
    -
    3.2.1.31. sshrm
    +
    +
    3.2.1.31. sshrm

    This programs simply runs ssh-keygen on the last host that I tried to ssh into. I need this frequently when working with cloud-init usually. @@ -5518,8 +5509,8 @@ in

    -
    -
    3.2.3.1.1. Personal
    +
    +
    3.2.3.1.1. Personal
    { lib, config, ... }:
    @@ -5589,8 +5580,8 @@ in
     
    -
    -
    3.2.3.1.2. Chaostheatre
    +
    +
    3.2.3.1.2. Chaostheatre
    { lib, config, ... }:
    @@ -5652,8 +5643,8 @@ in
     
    -
    -
    3.2.3.1.3. toto
    +
    +
    3.2.3.1.3. toto
    { lib, config, ... }:
    @@ -5685,8 +5676,8 @@ in
     
    -
    -
    3.2.3.1.4. Work
    +
    +
    3.2.3.1.4. Work
    { lib, config, ... }:
    @@ -5707,8 +5698,8 @@ in
     
    -
    -
    3.2.3.1.5. Framework
    +
    +
    3.2.3.1.5. Framework
    { lib, config, ... }:
    @@ -5729,8 +5720,8 @@ in
     
    -
    -
    3.2.3.1.6. AMD CPU
    +
    +
    3.2.3.1.6. AMD CPU
    { lib, config, ... }:
    @@ -5751,8 +5742,8 @@ in
     
    -
    -
    3.2.3.1.7. AMD GPU
    +
    +
    3.2.3.1.7. AMD GPU
    { lib, config, ... }:
    @@ -5773,8 +5764,8 @@ in
     
    -
    -
    3.2.3.1.8. Hibernation
    +
    +
    3.2.3.1.8. Hibernation
    { lib, config, ... }:
    @@ -5795,8 +5786,8 @@ in
     
    -
    -
    3.2.3.1.9. BTRFS
    +
    +
    3.2.3.1.9. BTRFS
    { lib, config, ... }:
    @@ -5817,8 +5808,8 @@ in
     
    -
    -
    3.2.3.1.10. Local Server
    +
    +
    3.2.3.1.10. Local Server
    { lib, config, ... }:
    @@ -5847,6 +5838,7 @@ in
               navidrome = lib.mkDefault true;
               spotifyd = lib.mkDefault true;
               mpd = lib.mkDefault true;
    +          postgresql = lib.mkDefault true;
               matrix = lib.mkDefault true;
               nextcloud = lib.mkDefault true;
               immich = lib.mkDefault true;
    @@ -5871,8 +5863,8 @@ in
     
    -
    -
    3.2.3.1.11. OCI Sync Server
    +
    +
    3.2.3.1.11. OCI Sync Server
    { lib, config, ... }:
    @@ -5908,8 +5900,8 @@ in
     
    -
    -
    3.2.3.1.12. Moonside
    +
    +
    3.2.3.1.12. Moonside
    { lib, config, ... }:
    @@ -5963,8 +5955,8 @@ in
     
    -
    -
    3.2.3.2.1. Personal
    +
    +
    3.2.3.2.1. Personal
    { lib, config, ... }:
    @@ -6021,8 +6013,8 @@ in
     
    -
    -
    3.2.3.2.2. Chaostheatre
    +
    +
    3.2.3.2.2. Chaostheatre
    { lib, config, ... }:
    @@ -6074,8 +6066,8 @@ in
     
    -
    -
    3.2.3.2.3. toto
    +
    +
    3.2.3.2.3. toto
    { lib, config, ... }:
    @@ -6095,8 +6087,8 @@ in
     
    -
    -
    3.2.3.2.4. Work
    +
    +
    3.2.3.2.4. Work
    { lib, config, ... }:
    @@ -6116,8 +6108,8 @@ in
     
    -
    -
    3.2.3.2.5. Framework
    +
    +
    3.2.3.2.5. Framework
    { lib, config, ... }:
    @@ -6138,8 +6130,8 @@ in
     
    -
    -
    3.2.3.2.6. Darwin
    +
    +
    3.2.3.2.6. Darwin
    { lib, config, ... }:
    @@ -6157,8 +6149,8 @@ in
     
    -
    -
    3.2.3.2.7. Local Server
    +
    +
    3.2.3.2.7. Local Server
    { lib, config, ... }:
    @@ -6405,12 +6397,12 @@ in
     
    -
    -

    3.2.5. Auxiliary files

    +
    +

    3.2.5. Auxiliary files

    -
    -
    3.2.5.1. extra-builtins
    +
    +
    3.2.5.1. extra-builtins
    @@ -6445,8 +6437,8 @@ in
     
    -
    -
    3.2.5.2. sops-decrypt-and-cache
    +
    +
    3.2.5.2. sops-decrypt-and-cache
    #!/usr/bin/env bash
    @@ -6493,8 +6485,8 @@ fi
     
    -
    -
    3.2.5.3. nix-topology
    +
    +
    3.2.5.3. nix-topology
    { config, ... }:
    @@ -6878,8 +6870,8 @@ A breakdown of the flags being set:
     
    -
    -
    3.3.1.4. Share configuration between nodes
    +
    +
    3.3.1.4. Share configuration between nodes
    { config, lib, outputs, ... }:
    @@ -7679,8 +7671,8 @@ Setup timezone and locale. I want to use the US layout, but have the rest adapte
     
    -
    -
    3.3.1.18. Meta options
    +
    +
    3.3.1.18. Meta options
    { lib, ... }:
    @@ -7703,8 +7695,8 @@ Setup timezone and locale. I want to use the US layout, but have the rest adapte
     
    -
    -
    3.3.1.19. Topology
    +
    +
    3.3.1.19. Topology
    { self, lib, config, ... }:
    @@ -7798,8 +7790,8 @@ in
     
    -
    -
    3.3.1.21. PII management
    +
    +
    3.3.1.21. PII management
    { config, inputs, lib, ... }:
    @@ -8194,8 +8186,8 @@ Most of the time I am using power-saver, however, it is good to be
     
    -
    -
    3.3.1.24.6. SwayOSD
    +
    +
    3.3.1.24.6. SwayOSD
    { lib, pkgs, config, ... }:
    @@ -9087,8 +9079,6 @@ in
           lego
         ];
     
    -    # users.users.acme = {};
    -
         sops = {
           # secrets.dnstokenfull = { owner = "acme"; };
           secrets.dnstokenfull = { };
    @@ -9203,6 +9193,7 @@ in
           user = serviceUser;
           settings.Port = servicePort;
           tokenKeyFile = config.sops.secrets.kavita.path;
    +      dataDir = "/Vault/data/kavita";
         };
     
         nodes.moonside.services.nginx = {
    @@ -9327,7 +9318,7 @@ in
     
         users = {
           groups = {
    -        "$(serviceGroup}" = {
    +        "${serviceGroup}" = {
               gid = 61593;
             };
           };
    @@ -9342,7 +9333,6 @@ in
           };
         };
     
    -
         hardware = {
           enableAllFirmware = lib.mkForce true;
         };
    @@ -9358,6 +9348,7 @@ in
             Port = servicePort;
             MusicFolder = "/Vault/Eternor/Music";
             PlaylistsPath = "./Playlists";
    +        AutoImportPlaylists = false;
             EnableSharing = true;
             EnableTranscodingConfig = true;
             Scanner.GroupAlbumReleases = true;
    @@ -9384,6 +9375,7 @@ in
             };
             UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png";
             UIWelcomeMessage = "~SwarselSound~";
    +        EnableInsightsCollector = false;
           };
         };
     
    @@ -9400,57 +9392,10 @@ in
               enableACME = true;
               forceSSL = true;
               acmeRoot = null;
    -          locations = {
    -            "/" = {
    -              proxyPass = "http://navidrome";
    -              proxyWebsockets = true;
    -              extraConfig = ''
    -                auth_request /oauth2/auth;
    -                error_page 401 = /oauth2/sign_in;
    -
    -                # pass information via X-User and X-Email headers to backend,
    -                # requires running with --set-xauthrequest flag (done by NixOS)
    -                auth_request_set $user   $upstream_http_x_auth_request_user;
    -                auth_request_set $email  $upstream_http_x_auth_request_email;
    -                proxy_set_header X-User  $user;
    -                proxy_set_header X-Email $email;
    -
    -                # if you enabled --pass-access-token, this will pass the token to the backend
    -                auth_request_set $token  $upstream_http_x_auth_request_access_token;
    -                proxy_set_header X-Access-Token $token;
    -
    -                # if you enabled --cookie-refresh, this is needed for it to work with auth_request
    -                auth_request_set $auth_cookie $upstream_http_set_cookie;
    -                add_header Set-Cookie $auth_cookie;
    -                proxy_redirect          http:// https://;
    -                proxy_read_timeout      600s;
    -                proxy_send_timeout      600s;
    -                proxy_buffering         off;
    -                proxy_request_buffering off;
    -                client_max_body_size    0;
    -              '';
    -            };
    -            "/oauth2/" = {
    -              proxyPass = "http://oauth2-proxy";
    -              extraConfig = ''
    -                proxy_set_header X-Scheme                $scheme;
    -                proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
    -              '';
    -            };
    -            "= /oauth2/auth" = {
    -              proxyPass = "http://oauth2-proxy/oauth2/auth";
    -              extraConfig = ''
    -                internal;
    -
    -                proxy_set_header X-Scheme         $scheme;
    -                # nginx auth_request includes headers but not body
    -                proxy_set_header Content-Length   "";
    -                proxy_pass_request_body           off;
    -              '';
    -            };
    -            "/share" = {
    -              proxyPass = "http://navidrome";
    -              proxyWebsockets = true;
    +          oauth2.enable = true;
    +          oauth2.allowedGroups = [ "navidrome_access" ];
    +          locations =
    +            let
                   extraConfig = ''
                     proxy_redirect          http:// https://;
                     proxy_read_timeout      600s;
    @@ -9458,25 +9403,29 @@ in
                     proxy_buffering         off;
                     proxy_request_buffering off;
                     client_max_body_size    0;
    -                proxy_set_header X-User  "";
    -                proxy_set_header X-Email "";
                   '';
    +            in
    +            {
    +              "/" = {
    +                proxyPass = "http://navidrome";
    +                proxyWebsockets = true;
    +                inherit extraConfig;
    +              };
    +              "/share" = {
    +                proxyPass = "http://navidrome";
    +                proxyWebsockets = true;
    +                setOauth2Headers = false;
    +                bypassAuth = true;
    +                inherit extraConfig;
    +              };
    +              "/rest" = {
    +                proxyPass = "http://navidrome";
    +                proxyWebsockets = true;
    +                setOauth2Headers = false;
    +                bypassAuth = true;
    +                inherit extraConfig;
    +              };
                 };
    -            "/rest" = {
    -              proxyPass = "http://navidrome";
    -              proxyWebsockets = true;
    -              extraConfig = ''
    -                proxy_redirect          http:// https://;
    -                proxy_read_timeout      600s;
    -                proxy_send_timeout      600s;
    -                proxy_buffering         off;
    -                proxy_request_buffering off;
    -                client_max_body_size    0;
    -                proxy_set_header X-User  "";
    -                proxy_set_header X-Email "";
    -              '';
    -            };
    -          };
             };
           };
         };
    @@ -9493,21 +9442,27 @@ in
     
    { lib, config, ... }:
    +let
    +  servicePort = 1025;
    +  serviceName = "spotifyd";
    +  serviceUser = "spotifyd";
    +  serviceGroup = serviceUser;
    +in
     {
    -  options.swarselsystems.modules.server.spotifyd = lib.mkEnableOption "enable spotifyd on server";
    -  config = lib.mkIf config.swarselsystems.modules.server.spotifyd {
    -    users.groups.spotifyd = {
    +  options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
    +    users.groups."${serviceGroup}" = {
           gid = 65136;
         };
     
    -    users.users.spotifyd = {
    +    users.users."${serviceUser}" = {
           isSystemUser = true;
           uid = 65136;
    -      group = "spotifyd";
    +      group = serviceGroup;
           extraGroups = [ "audio" "utmp" "pipewire" ];
         };
     
    -    networking.firewall.allowedTCPPorts = [ 1025 ];
    +    networking.firewall.allowedTCPPorts = [ servicePort ];
     
         services.pipewire.systemWide = true;
     
    @@ -9520,7 +9475,7 @@ in
               device = "sysdefault:CARD=PCH";
               device_name = "SwarselSpot";
               mixer = "alsa";
    -          zeroconf_port = 1025;
    +          zeroconf_port = servicePort;
             };
           };
         };
    @@ -9625,11 +9580,36 @@ in
     
    +
    +
    3.3.2.14. postgresql
    +
    +
    +
    { config, lib, pkgs, ... }:
    +let
    +  serviceName = "postgresql";
    +  postgresVersion = 14;
    +in
    +{
    +  options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
    +    services = {
    +      postgresql = {
    +        enable = true;
    +        package = pkgs."postgresql_${builtins.toString postgresVersion}";
    +        dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}";
    +      };
    +    };
    +  };
    +}
    +
    +
    +
    +
    -
    3.3.2.14. matrix
    +
    3.3.2.15. matrix
    -
    { config, lib, pkgs, sops, ... }:
    +
    { lib, config, pkgs, ... }:
     let
       matrixDomain = "swatrix.swarsel.win";
       serviceName = "matrix";
    @@ -9747,12 +9727,16 @@ in
     
           matrix-synapse = {
             enable = true;
    +        dataDir = "/Vault/data/matrix-synapse";
             settings = {
    -          app_service_config_files = [
    -            "/var/lib/matrix-synapse/telegram-registration.yaml"
    -            "/var/lib/matrix-synapse/whatsapp-registration.yaml"
    -            "/var/lib/matrix-synapse/signal-registration.yaml"
    -            "/var/lib/matrix-synapse/doublepuppet.yaml"
    +          app_service_config_files = let
    +            inherit (config.services.matrix-synapse) dataDir;
    +          in
    +            [
    +            "${dataDir}/telegram-registration.yaml"
    +            "${dataDir}/whatsapp-registration.yaml"
    +            "${dataDir}/signal-registration.yaml"
    +            "${dataDir}/doublepuppet.yaml"
               ];
               server_name = matrixDomain;
               public_baseurl = "https://${matrixDomain}";
    @@ -9971,7 +9955,7 @@ in
     
    -
    3.3.2.15. nextcloud
    +
    3.3.2.16. nextcloud
    { pkgs, lib, config, ... }:
    @@ -10007,7 +9991,7 @@ in
             };
             package = pkgs.nextcloud31;
             hostName = serviceDomain;
    -        home = "/Vault/apps/nextcloud";
    +        home = "/Vault/data/nextcloud";
             datadir = "/Vault/data/nextcloud";
             https = true;
             configureRedis = true;
    @@ -10052,7 +10036,7 @@ in
     
    -
    3.3.2.16. immich
    +
    3.3.2.17. immich
    { lib, config, ... }:
    @@ -10077,7 +10061,7 @@ in
           host = "0.0.0.0";
           port = servicePort;
           openFirewall = true;
    -      mediaLocation = "/Vault/Eternor/Immich";
    +      mediaLocation = "/Vault/Eternor/Immich"; # dataDir
           environment = {
             IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003";
           };
    @@ -10127,7 +10111,7 @@ in
     
    -
    3.3.2.17. paperless (tika, gotenberg)
    +
    3.3.2.18. paperless (tika, gotenberg)

    This is my personal document management system. It automatically pulls documents from several sources, the only manual step for physical documents is to put them in my scanner and use email delivery. @@ -10269,12 +10253,27 @@ in

    -
    3.3.2.18. transmission
    +
    3.3.2.19. transmission
    { self, pkgs, lib, config, ... }:
     let
       serviceDomain = "store.swarsel.win";
    +  lidarrUser = "lidarr";
    +  lidarrGroup = lidarrUser;
    +  lidarrPort = 8686;
    +  radarrUser = "radarr";
    +  radarrGroup = radarrUser;
    +  radarrPort = 7878;
    +  sonarrUser = "sonarr";
    +  sonarrGroup = sonarrUser;
    +  sonarrPort = 8989;
    +  readarrUser = "readarr";
    +  readarrGroup = readarrUser;
    +  readarrPort = 8787;
    +  prowlarrUser = "prowlarr";
    +  prowlarrGroup = prowlarrUser;
    +  prowlarrPort = 9696;
     in
     {
       options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
    @@ -10286,11 +10285,11 @@ in
             dockeruser = {
               gid = 1155;
             };
    -        radarr = { };
    -        readarr = { };
    -        sonarr = { };
    -        lidarr = { };
    -        prowlarr = { };
    +        "${radarrGroup}" = { };
    +        "${readarrGroup}" = { };
    +        "${sonarrGroup}" = { };
    +        "${lidarrGroup}" = { };
    +        "${prowlarrGroup}" = { };
           };
           users = {
             dockeruser = {
    @@ -10299,29 +10298,29 @@ in
               group = "docker";
               extraGroups = [ "users" ];
             };
    -        radarr = {
    +        "${radarrUser}" = {
               isSystemUser = true;
    -          group = "radarr";
    +          group = radarrGroup;
               extraGroups = [ "users" ];
             };
    -        readarr = {
    +        "${readarrGroup}" = {
               isSystemUser = true;
    -          group = "readarr";
    +          group = readarrGroup;
               extraGroups = [ "users" ];
             };
    -        sonarr = {
    +        "${sonarrGroup}" = {
               isSystemUser = true;
    -          group = "sonarr";
    +          group = sonarrGroup;
               extraGroups = [ "users" ];
             };
    -        lidarr = {
    +        "${lidarrUser}" = {
               isSystemUser = true;
    -          group = "lidarr";
    +          group = lidarrGroup;
               extraGroups = [ "users" ];
             };
    -        prowlarr = {
    +        "${prowlarrGroup}" = {
               isSystemUser = true;
    -          group = "prowlarr";
    +          group = prowlarrGroup;
               extraGroups = [ "users" ];
             };
           };
    @@ -10347,32 +10346,45 @@ in
         services = {
           radarr = {
             enable = true;
    +        user = radarrUser;
    +        group = radarrGroup;
    +        settings.server.port = radarrPort;
             openFirewall = true;
    -        dataDir = "/Vault/apps/radarr";
    +        dataDir = "/Vault/data/radarr";
           };
           readarr = {
             enable = true;
    +        user = readarrUser;
    +        group = readarrGroup;
    +        settings.server.port = readarrPort;
             openFirewall = true;
    -        dataDir = "/Vault/apps/readarr";
    +        dataDir = "/Vault/data/readarr";
           };
           sonarr = {
             enable = true;
    +        user = sonarrUser;
    +        group = sonarrGroup;
    +        settings.server.port = sonarrPort;
             openFirewall = true;
    -        dataDir = "/Vault/apps/sonarr";
    +        dataDir = "/Vault/data/sonarr";
           };
           lidarr = {
             enable = true;
    +        user = lidarrUser;
    +        group = lidarrGroup;
    +        settings.server.port = lidarrPort;
             openFirewall = true;
    -        dataDir = "/Vault/apps/lidarr";
    +        dataDir = "/Vault/data/lidarr";
           };
           prowlarr = {
             enable = true;
    +        settings.server.port = prowlarrPort;
             openFirewall = true;
           };
     
           nginx = {
             virtualHosts = {
    -          "store.swarsel.win" = {
    +          "${serviceDomain}" = {
                 enableACME = false;
                 forceSSL = false;
                 acmeRoot = null;
    @@ -10384,31 +10396,31 @@ in
                     '';
                   };
                   "/radarr" = {
    -                proxyPass = "http://localhost:7878";
    +                proxyPass = "http://localhost:${builtins.toString radarrPort}";
                     extraConfig = ''
                       client_max_body_size    0;
                     '';
                   };
                   "/readarr" = {
    -                proxyPass = "http://localhost:8787";
    +                proxyPass = "http://localhost:${builtins.toString readarrPort}";
                     extraConfig = ''
                       client_max_body_size    0;
                     '';
                   };
                   "/sonarr" = {
    -                proxyPass = "http://localhost:8989";
    +                proxyPass = "http://localhost:${builtins.toString sonarrPort}";
                     extraConfig = ''
                       client_max_body_size    0;
                     '';
                   };
                   "/lidarr" = {
    -                proxyPass = "http://localhost:8686";
    +                proxyPass = "http://localhost:${builtins.toString lidarrPort}";
                     extraConfig = ''
                       client_max_body_size    0;
                     '';
                   };
                   "/prowlarr" = {
    -                proxyPass = "http://localhost:9696";
    +                proxyPass = "http://localhost:${builtins.toString prowlarrPort}";
                     extraConfig = ''
                       client_max_body_size    0;
                     '';
    @@ -10426,7 +10438,7 @@ in
     
    -
    3.3.2.19. syncthing
    +
    3.3.2.20. syncthing
    { lib, config, ... }:
    @@ -10457,7 +10469,7 @@ in
           user = serviceUser;
           group = serviceGroup;
           dataDir = "/Vault/data/syncthing";
    -      configDir = "/Vault/apps/syncthing";
    +      configDir = "/Vault/data/syncthing/.config/syncthing";
           guiAddress = "0.0.0.0:${builtins.toString servicePort}";
           openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
           relay.enable = false;
    @@ -10515,16 +10527,16 @@ in
                 devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
                 id = "hgp9s-fyq3p";
               };
    -          "Documents" = {
    -            path = "/Vault/data/syncthing/Documents";
    -            type = "receiveonly";
    -            versioning = {
    -              type = "simple";
    -              params.keep = "5";
    -            };
    -            devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
    -            id = "hgr3d-pfu3w";
    -          };
    +          # "Documents" = {
    +          #   path = "/Vault/data/syncthing/Documents";
    +          #   type = "receiveonly";
    +          #   versioning = {
    +          #     type = "simple";
    +          #     params.keep = "5";
    +          #   };
    +          #   devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
    +          #   id = "hgr3d-pfu3w";
    +          # };
             };
           };
         };
    @@ -10560,7 +10572,7 @@ in
     
    -
    3.3.2.20. restic
    +
    3.3.2.21. restic

    This manages backups for my pictures and obsidian files. @@ -10599,7 +10611,6 @@ in "/Vault/Eternor/Paperless" "/Vault/Eternor/Bilder" "/Vault/Eternor/Immich" - "/Vault/familymedia" ]; pruneOpts = [ "--keep-daily 3" @@ -10627,7 +10638,7 @@ in

    -
    3.3.2.21. monitoring (Grafana)
    +
    3.3.2.22. monitoring (Grafana)

    This section exposes several metrics that I use to check the health of my server. I need to expand on the exporters section at some point, but for now I have everything I need. @@ -10858,7 +10869,7 @@ in

    -
    3.3.2.22. Jenkins
    +
    3.3.2.23. Jenkins

    This is a WIP Jenkins instance. It is used to automatically build a new system when pushes to the main repository are detected. I have turned this service off for now however, as I actually prefer to start my builds manually. @@ -10866,30 +10877,40 @@ This is a WIP Jenkins instance. It is used to automatically build a new system w

    { pkgs, lib, config, ... }:
    +let
    +  serviceDomain = "servant.swarsel.win";
    +  servicePort = 8088;
    +  serviceName = "jenkins";
    +in
     {
    -  options.swarselsystems.modules.server.jenkins = lib.mkEnableOption "enable jenkins on server";
    -  config = lib.mkIf config.swarselsystems.modules.server.jenkins {
    +  options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
     
         services.jenkins = {
           enable = true;
           withCLI = true;
           port = 8088;
           packages = [ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ];
    -      listenAddress = "127.0.0.1";
    +      listenAddress = "0.0.0.0";
           home = "/Vault/apps/jenkins";
         };
     
    -
    -
         services.nginx = {
    +      upstreams = {
    +        "${serviceName}" = {
    +          servers = {
    +            "192.168.1.2:${builtins.toString servicePort}" = { };
    +          };
    +        };
    +      };
           virtualHosts = {
    -        "servant.swarsel.win" = {
    +        "${serviceDomain}" = {
               enableACME = true;
               forceSSL = true;
               acmeRoot = null;
               locations = {
                 "/" = {
    -              proxyPass = "http://localhost:8088";
    +              proxyPass = "http://${serviceName}";
                   extraConfig = ''
                     client_max_body_size 0;
                   '';
    @@ -10906,7 +10927,7 @@ This is a WIP Jenkins instance. It is used to automatically build a new system w
     
    -
    3.3.2.23. Emacs elfeed (RSS Server)
    +
    3.3.2.24. Emacs elfeed (RSS Server)

    This was an approach of hosting an RSS server from within emacs. That would have been useful as it would have allowed me to allow my feeds from any device. However, it proved impossible to do bidirectional syncing, so I abandoned this configuration in favor of FreshRSS. @@ -10934,7 +10955,7 @@ This was an approach of hosting an RSS server from within emacs. That would have

    -
    3.3.2.24. FreshRSS
    +
    3.3.2.25. FreshRSS

    FreshRSS is a more 'classical' RSS aggregator that I can just host as a distinct service. This also has its upsides because I jave more control over the state this way. @@ -10957,24 +10978,26 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with let serviceName = "freshrss"; serviceDomain = "signpost.swarsel.win"; + serviceUser = "freshrss"; + serviceGroup = serviceName; in { options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server"; config = lib.mkIf config.swarselsystems.modules.server.freshrss { - users.users.freshrss = { + users.users."${serviceUser}" = { extraGroups = [ "users" ]; - group = "freshrss"; + group = serviceGroup; isSystemUser = true; }; - users.groups.freshrss = { }; + users.groups."${serviceGroup}" = { }; sops = { secrets = { - fresh = { owner = "freshrss"; }; - "kanidm-freshrss-client" = { owner = "freshrss"; group = "freshrss"; mode = "0440"; }; - "oidc-crypto-key" = { owner = "freshrss"; group = "freshrss"; mode = "0440"; }; + fresh = { owner = serviceUser; }; + "kanidm-freshrss-client" = { owner = serviceUser; group = serviceGroup; mode = "0440"; }; + "oidc-crypto-key" = { owner = serviceUser; group = serviceGroup; mode = "0440"; }; }; # templates = { @@ -11030,95 +11053,60 @@ in enableACME = true; forceSSL = true; acmeRoot = null; + oauth2.enable = true; + oauth2.allowedGroups = [ "ttrss_access" ]; locations = { "/" = { proxyPass = "http://${serviceName}"; - extraConfig = '' - auth_request /oauth2/auth; - error_page 401 = /oauth2/sign_in; - - # pass information via X-User and X-Email headers to backend, - # requires running with --set-xauthrequest flag (done by NixOS) - auth_request_set $user $upstream_http_x_auth_request_user; - auth_request_set $email $upstream_http_x_auth_request_email; - proxy_set_header X-User $user; - proxy_set_header X-Email $email; - proxy_set_header Remote-User $user; - - # if you enabled --pass-access-token, this will pass the token to the backend - auth_request_set $token $upstream_http_x_auth_request_access_token; - proxy_set_header X-Access-Token $token; - - # if you enabled --cookie-refresh, this is needed for it to work with auth_request - auth_request_set $auth_cookie $upstream_http_set_cookie; - add_header Set-Cookie $auth_cookie; - ''; - }; - "/oauth2/" = { - proxyPass = "http://oauth2-proxy"; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - ''; - }; - "= /oauth2/auth" = { - proxyPass = "http://oauth2-proxy/oauth2/auth"; - extraConfig = '' - internal; - - proxy_set_header X-Scheme $scheme; - # nginx auth_request includes headers but not body - proxy_set_header Content-Length ""; - proxy_pass_request_body off; - ''; }; "/api" = { proxyPass = "http://${serviceName}"; + setOauth2Headers = false; + bypassAuth = true; }; }; }; }; }; }; - }

    -
    3.3.2.25. forgejo (git server)
    +
    3.3.2.26. forgejo (git server)
    { lib, config, pkgs, ... }:
     let
    -  forgejoDomain = "swagit.swarsel.win";
    +  serviceDomain = "swagit.swarsel.win";
    +  servicePort = 3000;
    +  serviceUser = "forgejo";
    +  serviceGroup = serviceUser;
    +  serviceName = "forgejo";
     in
     {
    -  options.swarselsystems.modules.server.forgejo = lib.mkEnableOption "enable forgejo on server";
    -  config = lib.mkIf config.swarselsystems.modules.server.forgejo {
    +  options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
     
    -    networking.firewall.allowedTCPPorts = [ 3000 ];
    +    networking.firewall.allowedTCPPorts = [ servicePort ];
     
    -    users.users.forgejo = {
    -      group = "forgejo";
    +    users.users."${serviceUser}" = {
    +      group = serviceGroup;
           isSystemUser = true;
         };
     
    -    users.groups.forgejo = { };
    +    users.groups."${serviceGroup}" = { };
     
         sops.secrets = {
    -      kanidm-forgejo-client = {
    -        owner = "forgejo";
    -        group = "forgejo";
    -        mode = "0440";
    -      };
    +      kanidm-forgejo-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
         };
     
         services.forgejo = {
           enable = true;
    -      user = "forgejo";
    -      group = "forgejo";
    +      user = serviceUser;
    +      group = serviceGroup;
           lfs.enable = lib.mkDefault true;
           settings = {
             DEFAULT = {
    @@ -11126,10 +11114,10 @@ in
             };
             server = {
               PROTOCOL = "http";
    -          HTTP_PORT = 3000;
    +          HTTP_PORT = servicePort;
               HTTP_ADDR = "0.0.0.0";
    -          DOMAIN = forgejoDomain;
    -          ROOT_URL = "https://${forgejoDomain}";
    +          DOMAIN = serviceDomain;
    +          ROOT_URL = "https://${serviceDomain}";
             };
             # federation.ENABLED = true;
             service = {
    @@ -11214,14 +11202,21 @@ in
         };
     
         services.nginx = {
    +      upstreams = {
    +        "${serviceName}" = {
    +          servers = {
    +            "192.168.1.2:${builtins.toString servicePort}" = { };
    +          };
    +        };
    +      };
           virtualHosts = {
    -        "swagit.swarsel.win" = {
    +        "${serviceDomain}" = {
               enableACME = true;
               forceSSL = true;
               acmeRoot = null;
               locations = {
                 "/" = {
    -              proxyPass = "http://localhost:3000";
    +              proxyPass = "http://${serviceName}";
                   extraConfig = ''
                     client_max_body_size 0;
                   '';
    @@ -11238,18 +11233,20 @@ in
     
    -
    3.3.2.26. Anki Sync Server
    +
    3.3.2.27. Anki Sync Server
    { lib, config, ... }:
     let
       serviceDomain = "synki.swarsel.win";
    +  servicePort = 27701;
    +  serviceName = "ankisync";
     in
     {
    -  options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
    -  config = lib.mkIf config.swarselsystems.modules.server.ankisync {
    +  options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
     
    -    networking.firewall.allowedTCPPorts = [ 22701 ];
    +    networking.firewall.allowedTCPPorts = [ servicePort ];
     
         sops.secrets.swarsel = { owner = "root"; };
     
    @@ -11260,7 +11257,7 @@ in
     
         services.anki-sync-server = {
           enable = true;
    -      port = 27701;
    +      port = servicePort;
           address = "0.0.0.0";
           openFirewall = true;
           users = [
    @@ -11272,6 +11269,13 @@ in
         };
     
         services.nginx = {
    +      upstreams = {
    +        "${serviceName}" = {
    +          servers = {
    +            "192.168.1.2:${builtins.toString servicePort}" = { };
    +          };
    +        };
    +      };
           virtualHosts = {
             "${serviceDomain}" = {
               enableACME = true;
    @@ -11279,7 +11283,7 @@ in
               acmeRoot = null;
               locations = {
                 "/" = {
    -              proxyPass = "http://localhost:27701";
    +              proxyPass = "http://${serviceName}";
                   extraConfig = ''
                     client_max_body_size 0;
                   '';
    @@ -11295,9 +11299,9 @@ in
     
    -
    -
    3.3.2.27. kanidm
    -
    +
    +
    3.3.2.28. kanidm
    +

    The forgejo configuration is a little broken and will show a 500 error when signing in through kanidm. However, when pressing back and refreshing the page, I am logged in. Currently I cannot be bothered to fix this.

    @@ -11553,9 +11557,9 @@ in
    -
    -
    3.3.2.28. oauth2-proxy
    -
    +
    +
    3.3.2.29. oauth2-proxy
    +
    { lib, config, ... }:
     let
    @@ -11564,7 +11568,113 @@ let
       oauth2ProxyPort = 3004;
     in
     {
    -  options.swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
    +  options = {
    +    swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
    +    services.nginx.virtualHosts = lib.mkOption {
    +      type = lib.types.attrsOf (
    +        lib.types.submodule (
    +          { config, ... }:
    +          {
    +            options.oauth2 = {
    +              enable = lib.mkEnableOption "access protection of this virtualHost using oauth2-proxy.";
    +              allowedGroups = lib.mkOption {
    +                type = lib.types.listOf lib.types.str;
    +                default = [ ];
    +                description = ''
    +                  A list of kanidm groups that are allowed to access this resource, or the
    +                  empty list to allow any authenticated client.
    +                '';
    +              };
    +              X-User = lib.mkOption {
    +                type = lib.types.str;
    +                default = "$upstream_http_x_auth_request_user";
    +                description = "The variable to set as X-User";
    +              };
    +              X-Email = lib.mkOption {
    +                type = lib.types.str;
    +                default = "$upstream_http_x_auth_request_email";
    +                description = "The variable to set as X-Email";
    +              };
    +              X-Access-Token = lib.mkOption {
    +                type = lib.types.str;
    +                default = "$upstream_http_x_auth_request_access_token";
    +                description = "The variable to set as X-Access-Token";
    +              };
    +            };
    +            options.locations = lib.mkOption {
    +              type = lib.types.attrsOf (
    +                lib.types.submodule (locationSubmodule: {
    +                  options = {
    +                    setOauth2Headers = lib.mkOption {
    +                      type = lib.types.bool;
    +                      default = true;
    +                      description = "Whether to add oauth2 headers to this location. Only takes effect is oauth2 is actually enabled on the parent vhost.";
    +                    };
    +                    bypassAuth = lib.mkOption {
    +                      type = lib.types.bool;
    +                      default = false;
    +                      description = "Whether to set auth_request off for this location. Only takes effect is oauth2 is actually enabled on the parent vhost.";
    +                    };
    +                  };
    +                  config = lib.mkIf config.oauth2.enable {
    +                    extraConfig = lib.optionalString locationSubmodule.config.setOauth2Headers ''
    +                      proxy_set_header X-User         $user;
    +                      proxy_set_header Remote-User    $user;
    +                      proxy_set_header X-Email        $email;
    +                      proxy_set_header X-Access-Token $token;
    +                      add_header Set-Cookie           $auth_cookie;
    +                    '' + lib.optionalString locationSubmodule.config.bypassAuth ''
    +                      auth_request off;
    +                    '';
    +                  };
    +                })
    +              );
    +            };
    +            config = lib.mkIf config.oauth2.enable {
    +              extraConfig = ''
    +                auth_request /oauth2/auth;
    +                error_page 401 = /oauth2/sign_in;
    +
    +                # set variables that can be used in locations.<name>.extraConfig
    +                # pass information via X-User and X-Email headers to backend,
    +                # requires running with --set-xauthrequest flag
    +                auth_request_set $user  ${config.oauth2.X-User};
    +                auth_request_set $email ${config.oauth2.X-Email};
    +                # if you enabled --pass-access-token, this will pass the token to the backend
    +                auth_request_set $token ${config.oauth2.X-Access-Token};
    +                # if you enabled --cookie-refresh, this is needed for it to work with auth_request
    +                auth_request_set $auth_cookie $upstream_http_set_cookie;
    +              '';
    +              locations = {
    +                "/oauth2/" = {
    +                  proxyPass = "http://oauth2-proxy";
    +                  setOauth2Headers = false;
    +                  bypassAuth = true;
    +                  extraConfig = ''
    +                    proxy_set_header X-Scheme                $scheme;
    +                    proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
    +                  '';
    +                };
    +                "= /oauth2/auth" = {
    +                  proxyPass = "http://oauth2-proxy/oauth2/auth" + lib.optionalString (config.oauth2.allowedGroups != [ ]) "?allowed_groups=${lib.concatStringsSep "," config.oauth2.allowedGroups}";
    +                  setOauth2Headers = false;
    +                  bypassAuth = true;
    +                  extraConfig = ''
    +                    internal;
    +
    +                    proxy_set_header X-Scheme       $scheme;
    +                    # nginx auth_request includes headers but not body
    +                    proxy_set_header Content-Length "";
    +                    proxy_pass_request_body         off;
    +                  '';
    +                };
    +              };
    +            };
    +          }
    +        )
    +      );
    +    };
    +  };
       config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
     
         sops = {
    @@ -11668,9 +11778,9 @@ in
     
    -
    -
    3.3.2.29. Firefly-III
    -
    +
    +
    3.3.2.30. Firefly-III
    +
    { self, lib, config, ... }:
     let
    @@ -11726,12 +11836,11 @@ in
               "${fireflyDomain}" = {
                 locations = {
                   "/api" = {
    +                setOauth2Headers = false;
                     extraConfig = ''
                       index index.php;
                       try_files $uri $uri/ /index.php?$query_string;
                       add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
    -                  proxy_set_header X-User  "";
    -                  proxy_set_header X-Email "";
                     '';
                   };
                 };
    @@ -11753,52 +11862,18 @@ in
               enableACME = true;
               forceSSL = true;
               acmeRoot = null;
    +          oauth2.enable = true;
    +          oauth2.allowedGroups = [ "firefly_access" ];
               # main config is automatically added by nixos firefly config.
               # hence, only provide certificate
               locations = {
                 "/" = {
                   proxyPass = "http://${serviceName}";
    -              extraConfig = ''
    -                auth_request /oauth2/auth;
    -                error_page 401 = /oauth2/sign_in;
    -
    -                # pass information via X-User and X-Email headers to backend,
    -                # requires running with --set-xauthrequest flag (done by NixOS)
    -                auth_request_set $user   $upstream_http_x_auth_request_user;
    -                auth_request_set $email  $upstream_http_x_auth_request_email;
    -                proxy_set_header X-User  $user;
    -                proxy_set_header X-Email $email;
    -
    -                # if you enabled --pass-access-token, this will pass the token to the backend
    -                auth_request_set $token  $upstream_http_x_auth_request_access_token;
    -                proxy_set_header X-Access-Token $token;
    -
    -                # if you enabled --cookie-refresh, this is needed for it to work with auth_request
    -                auth_request_set $auth_cookie $upstream_http_set_cookie;
    -                add_header Set-Cookie $auth_cookie;
    -              '';
    -            };
    -            "/oauth2/" = {
    -              proxyPass = "http://oauth2-proxy";
    -              extraConfig = ''
    -
    -                          proxy_set_header X-Scheme                $scheme;
    -                          proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
    -                        '';
    -            };
    -            "= /oauth2/auth" = {
    -              proxyPass = "http://oauth2-proxy/oauth2/auth";
    -              extraConfig = ''
    -                internal;
    -
    -                proxy_set_header X-Scheme         $scheme;
    -                # nginx auth_request includes headers but not body
    -                proxy_set_header Content-Length   "";
    -                proxy_pass_request_body           off;
    -              '';
                 };
                 "/api" = {
                   proxyPass = "http://${serviceName}";
    +              setOauth2Headers = false;
    +              bypassAuth = true;
                 };
               };
             };
    @@ -11810,9 +11885,9 @@ in
     
    -
    -
    3.3.2.30. Koillection
    -
    +
    +
    3.3.2.31. Koillection
    +
    { self, lib, config, ... }:
     let
    @@ -12149,8 +12224,8 @@ This smashes Atmosphere 1.3.2 on the switch, which is what I am currenty using.
     
    -
    -
    3.3.4.6. Framework
    +
    +
    3.3.4.6. Framework

    This holds configuration that is specific to framework laptops. @@ -12188,8 +12263,8 @@ This holds configuration that is specific to framework laptops.

    -
    -
    3.3.4.7. AMD CPU
    +
    +
    3.3.4.7. AMD CPU
    { lib, config, ... }:
    @@ -12205,8 +12280,8 @@ This holds configuration that is specific to framework laptops.
     
    -
    -
    3.3.4.8. AMD GPU
    +
    +
    3.3.4.8. AMD GPU
    { lib, config, ... }:
    @@ -12228,8 +12303,8 @@ This holds configuration that is specific to framework laptops.
     
    -
    -
    3.3.4.9. Hibernation
    +
    +
    3.3.4.9. Hibernation
    { lib, config, ... }:
    @@ -12260,8 +12335,8 @@ This holds configuration that is specific to framework laptops.
     
    -
    -
    3.3.4.10. BTRFS
    +
    +
    3.3.4.10. BTRFS
    { lib, config, ... }:
    @@ -15206,8 +15281,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
     
    -
    -
    3.4.1.29.4. SwayOSD
    +
    +
    3.4.1.29.4. SwayOSD
    { lib, config, ... }:
    @@ -16349,7 +16424,7 @@ in
             { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }
             { command = "nm-applet"; }
             { command = "feishin"; }
    -        { command = "teams-for-linux"; }
    +        { command = "teams-for-linux --disableGpu=true --minimized=true --trayIconEnabled=true"; }
             { command = "1password"; }
           ];
           monitors = {
    @@ -16453,8 +16528,8 @@ in
     
    -
    -
    3.4.4.3. Framework
    +
    +
    3.4.4.3. Framework

    This holds configuration that is specific to framework laptops. @@ -20294,8 +20369,8 @@ autocmd DocStart vc-impimba-1.m.imp.ac.at/ui/webconsole mode ignore

    -
    -

    6.3. tridactyl theme

    +
    +

    6.3. tridactyl theme

    @@ -20792,7 +20867,7 @@ sync USER HOST:
     

    Author: Leon Schwarzäugl

    -

    Created: 2025-06-16 Mo 00:41

    +

    Created: 2025-06-16 Mo 23:03

    Validate

    diff --git a/modules/nixos/server/immich.nix b/modules/nixos/server/immich.nix index 58fd660..d1ef9e1 100644 --- a/modules/nixos/server/immich.nix +++ b/modules/nixos/server/immich.nix @@ -20,7 +20,7 @@ in host = "0.0.0.0"; port = servicePort; openFirewall = true; - mediaLocation = "/Vault/Eternor/Immich"; + mediaLocation = "/Vault/Eternor/Immich"; # dataDir environment = { IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003"; }; diff --git a/modules/nixos/server/kavita.nix b/modules/nixos/server/kavita.nix index abc1c32..6efbe35 100644 --- a/modules/nixos/server/kavita.nix +++ b/modules/nixos/server/kavita.nix @@ -31,6 +31,7 @@ in user = serviceUser; settings.Port = servicePort; tokenKeyFile = config.sops.secrets.kavita.path; + dataDir = "/Vault/data/kavita"; }; nodes.moonside.services.nginx = { diff --git a/modules/nixos/server/matrix.nix b/modules/nixos/server/matrix.nix index c5f8808..432ecd3 100644 --- a/modules/nixos/server/matrix.nix +++ b/modules/nixos/server/matrix.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, sops, ... }: +{ lib, config, pkgs, ... }: let matrixDomain = "swatrix.swarsel.win"; serviceName = "matrix"; @@ -116,13 +116,18 @@ in matrix-synapse = { enable = true; + dataDir = "/Vault/data/matrix-synapse"; settings = { - app_service_config_files = [ - "/var/lib/matrix-synapse/telegram-registration.yaml" - "/var/lib/matrix-synapse/whatsapp-registration.yaml" - "/var/lib/matrix-synapse/signal-registration.yaml" - "/var/lib/matrix-synapse/doublepuppet.yaml" - ]; + app_service_config_files = + let + inherit (config.services.matrix-synapse) dataDir; + in + [ + "${dataDir}/telegram-registration.yaml" + "${dataDir}/whatsapp-registration.yaml" + "${dataDir}/signal-registration.yaml" + "${dataDir}/doublepuppet.yaml" + ]; server_name = matrixDomain; public_baseurl = "https://${matrixDomain}"; listeners = [ diff --git a/modules/nixos/server/navidrome.nix b/modules/nixos/server/navidrome.nix index 66d18a5..a440521 100644 --- a/modules/nixos/server/navidrome.nix +++ b/modules/nixos/server/navidrome.nix @@ -17,7 +17,7 @@ in users = { groups = { - "$(serviceGroup}" = { + "${serviceGroup}" = { gid = 61593; }; }; @@ -47,6 +47,7 @@ in Port = servicePort; MusicFolder = "/Vault/Eternor/Music"; PlaylistsPath = "./Playlists"; + AutoImportPlaylists = false; EnableSharing = true; EnableTranscodingConfig = true; Scanner.GroupAlbumReleases = true; @@ -73,6 +74,7 @@ in }; UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png"; UIWelcomeMessage = "~SwarselSound~"; + EnableInsightsCollector = false; }; }; diff --git a/modules/nixos/server/nextcloud.nix b/modules/nixos/server/nextcloud.nix index d452e61..af02c04 100644 --- a/modules/nixos/server/nextcloud.nix +++ b/modules/nixos/server/nextcloud.nix @@ -31,7 +31,7 @@ in }; package = pkgs.nextcloud31; hostName = serviceDomain; - home = "/Vault/apps/nextcloud"; + home = "/Vault/data/nextcloud"; datadir = "/Vault/data/nextcloud"; https = true; configureRedis = true; diff --git a/modules/nixos/server/nginx.nix b/modules/nixos/server/nginx.nix index 1538550..88bdee3 100644 --- a/modules/nixos/server/nginx.nix +++ b/modules/nixos/server/nginx.nix @@ -6,8 +6,6 @@ lego ]; - # users.users.acme = {}; - sops = { # secrets.dnstokenfull = { owner = "acme"; }; secrets.dnstokenfull = { }; diff --git a/modules/nixos/server/postgresql.nix b/modules/nixos/server/postgresql.nix new file mode 100644 index 0000000..52335d7 --- /dev/null +++ b/modules/nixos/server/postgresql.nix @@ -0,0 +1,17 @@ +{ config, lib, pkgs, ... }: +let + serviceName = "postgresql"; + postgresVersion = 14; +in +{ + options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server"; + config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" { + services = { + postgresql = { + enable = true; + package = pkgs."postgresql_${builtins.toString postgresVersion}"; + dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}"; + }; + }; + }; +} diff --git a/modules/nixos/server/restic.nix b/modules/nixos/server/restic.nix index 3611824..4044808 100644 --- a/modules/nixos/server/restic.nix +++ b/modules/nixos/server/restic.nix @@ -30,7 +30,6 @@ in "/Vault/Eternor/Paperless" "/Vault/Eternor/Bilder" "/Vault/Eternor/Immich" - "/Vault/familymedia" ]; pruneOpts = [ "--keep-daily 3" diff --git a/modules/nixos/server/syncthing.nix b/modules/nixos/server/syncthing.nix index c1053ce..65f8a00 100644 --- a/modules/nixos/server/syncthing.nix +++ b/modules/nixos/server/syncthing.nix @@ -26,7 +26,7 @@ in user = serviceUser; group = serviceGroup; dataDir = "/Vault/data/syncthing"; - configDir = "/Vault/apps/syncthing"; + configDir = "/Vault/data/syncthing/.config/syncthing"; guiAddress = "0.0.0.0:${builtins.toString servicePort}"; openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery relay.enable = false; @@ -84,16 +84,16 @@ in devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ]; id = "hgp9s-fyq3p"; }; - "Documents" = { - path = "/Vault/data/syncthing/Documents"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; - id = "hgr3d-pfu3w"; - }; + # "Documents" = { + # path = "/Vault/data/syncthing/Documents"; + # type = "receiveonly"; + # versioning = { + # type = "simple"; + # params.keep = "5"; + # }; + # devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; + # id = "hgr3d-pfu3w"; + # }; }; }; }; diff --git a/modules/nixos/server/transmission.nix b/modules/nixos/server/transmission.nix index b14fac9..39d6ed4 100644 --- a/modules/nixos/server/transmission.nix +++ b/modules/nixos/server/transmission.nix @@ -1,6 +1,21 @@ { self, pkgs, lib, config, ... }: let serviceDomain = "store.swarsel.win"; + lidarrUser = "lidarr"; + lidarrGroup = lidarrUser; + lidarrPort = 8686; + radarrUser = "radarr"; + radarrGroup = radarrUser; + radarrPort = 7878; + sonarrUser = "sonarr"; + sonarrGroup = sonarrUser; + sonarrPort = 8989; + readarrUser = "readarr"; + readarrGroup = readarrUser; + readarrPort = 8787; + prowlarrUser = "prowlarr"; + prowlarrGroup = prowlarrUser; + prowlarrPort = 9696; in { options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server"; @@ -12,11 +27,11 @@ in dockeruser = { gid = 1155; }; - radarr = { }; - readarr = { }; - sonarr = { }; - lidarr = { }; - prowlarr = { }; + "${radarrGroup}" = { }; + "${readarrGroup}" = { }; + "${sonarrGroup}" = { }; + "${lidarrGroup}" = { }; + "${prowlarrGroup}" = { }; }; users = { dockeruser = { @@ -25,29 +40,29 @@ in group = "docker"; extraGroups = [ "users" ]; }; - radarr = { + "${radarrUser}" = { isSystemUser = true; - group = "radarr"; + group = radarrGroup; extraGroups = [ "users" ]; }; - readarr = { + "${readarrGroup}" = { isSystemUser = true; - group = "readarr"; + group = readarrGroup; extraGroups = [ "users" ]; }; - sonarr = { + "${sonarrGroup}" = { isSystemUser = true; - group = "sonarr"; + group = sonarrGroup; extraGroups = [ "users" ]; }; - lidarr = { + "${lidarrUser}" = { isSystemUser = true; - group = "lidarr"; + group = lidarrGroup; extraGroups = [ "users" ]; }; - prowlarr = { + "${prowlarrGroup}" = { isSystemUser = true; - group = "prowlarr"; + group = prowlarrGroup; extraGroups = [ "users" ]; }; }; @@ -73,32 +88,45 @@ in services = { radarr = { enable = true; + user = radarrUser; + group = radarrGroup; + settings.server.port = radarrPort; openFirewall = true; - dataDir = "/Vault/apps/radarr"; + dataDir = "/Vault/data/radarr"; }; readarr = { enable = true; + user = readarrUser; + group = readarrGroup; + settings.server.port = readarrPort; openFirewall = true; - dataDir = "/Vault/apps/readarr"; + dataDir = "/Vault/data/readarr"; }; sonarr = { enable = true; + user = sonarrUser; + group = sonarrGroup; + settings.server.port = sonarrPort; openFirewall = true; - dataDir = "/Vault/apps/sonarr"; + dataDir = "/Vault/data/sonarr"; }; lidarr = { enable = true; + user = lidarrUser; + group = lidarrGroup; + settings.server.port = lidarrPort; openFirewall = true; - dataDir = "/Vault/apps/lidarr"; + dataDir = "/Vault/data/lidarr"; }; prowlarr = { enable = true; + settings.server.port = prowlarrPort; openFirewall = true; }; nginx = { virtualHosts = { - "store.swarsel.win" = { + "${serviceDomain}" = { enableACME = false; forceSSL = false; acmeRoot = null; @@ -110,31 +138,31 @@ in ''; }; "/radarr" = { - proxyPass = "http://localhost:7878"; + proxyPass = "http://localhost:${builtins.toString radarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/readarr" = { - proxyPass = "http://localhost:8787"; + proxyPass = "http://localhost:${builtins.toString readarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/sonarr" = { - proxyPass = "http://localhost:8989"; + proxyPass = "http://localhost:${builtins.toString sonarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/lidarr" = { - proxyPass = "http://localhost:8686"; + proxyPass = "http://localhost:${builtins.toString lidarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/prowlarr" = { - proxyPass = "http://localhost:9696"; + proxyPass = "http://localhost:${builtins.toString prowlarrPort}"; extraConfig = '' client_max_body_size 0; ''; diff --git a/profiles/nixos/localserver/default.nix b/profiles/nixos/localserver/default.nix index 67e4757..9d9c210 100644 --- a/profiles/nixos/localserver/default.nix +++ b/profiles/nixos/localserver/default.nix @@ -24,6 +24,7 @@ navidrome = lib.mkDefault true; spotifyd = lib.mkDefault true; mpd = lib.mkDefault true; + postgresql = lib.mkDefault true; matrix = lib.mkDefault true; nextcloud = lib.mkDefault true; immich = lib.mkDefault true;