diff --git a/lib/base64/ascii b/lib/base64/ascii
deleted file mode 100644
index 27ab38e..0000000
--- a/lib/base64/ascii
+++ /dev/null
@@ -1,3 +0,0 @@
-	
-
- !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
\ No newline at end of file
diff --git a/lib/base64/default.nix b/lib/base64/default.nix
deleted file mode 100644
index 93ba695..0000000
--- a/lib/base64/default.nix
+++ /dev/null
@@ -1,62 +0,0 @@
-{ inputs }:
-let
-  inherit (inputs.nixpkgs.lib)
-    concatLists
-    concatMapStrings
-    foldl'
-    genList
-    hasSuffix
-    imap0
-    length
-    mod
-    nameValuePair
-    stringToCharacters
-    sublist
-    substring
-    take
-    ;
-in
-rec {
-  base64Table = builtins.listToAttrs (
-    imap0 (i: c: nameValuePair c i) (
-      # The '=' is included so the main algorithm doesn't fail before we can trim the result
-      stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
-    )
-  );
-
-  # Generated using python3:
-  # print(''.join([ chr(n) for n in range(1, 256) ]), file=open('ascii', 'w'))
-  ascii = builtins.readFile ./ascii;
-
-  decode =
-    str:
-    let
-      paddingCount =
-        if hasSuffix "==" str then
-          2
-        else if hasSuffix "=" str then
-          1
-        else
-          0;
-
-      numbers64 = map (c: base64Table.${c}) (stringToCharacters str);
-
-      allBytes = concatLists (
-        genList (
-          i:
-          let
-            v = foldl' (acc: el: acc * 64 + el) 0 (sublist (i * 4) 4 numbers64);
-          in
-          [
-            (mod (v / 256 / 256) 256)
-            (mod (v / 256) 256)
-            (mod v 256)
-          ]
-        ) (length numbers64 / 4)
-      );
-
-      finalBytes = take (length allBytes - paddingCount) allBytes;
-
-    in
-    concatMapStrings (n: substring (n - 1) 1 ascii) finalBytes;
-}
diff --git a/lib/default.nix b/lib/default.nix
index 5707ed3..715954c 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,22 +1,8 @@
 { inputs, ... }:
 {
   mjallen-lib = {
-    # Import module utilities
     module = import ./module { inherit inputs; };
-
-    # Import file utilities
     file = import ./file { inherit inputs; };
-
-    # Import system utilities
-    system = import ./system { inherit inputs; };
-
-    # Import reverse proxy utilities
-    reverseproxy = import ./reverseproxy { inherit inputs; };
-
-    # Import examples
-    examples = import ./examples { inherit inputs; };
-
-    # Import versioning utilities
     versioning = import ./versioning {
       lib = inputs.nixpkgs.lib;
       inherit inputs;
diff --git a/lib/examples/default.nix b/lib/examples/default.nix
deleted file mode 100644
index 4b15ff4..0000000
--- a/lib/examples/default.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{ ... }:
-{
-  # Import all examples
-  sops = import ./sops.nix;
-  homeSops = import ./home-sops.nix;
-  fileUtils = import ./file-utils.nix;
-  systemUtils = import ./system-utils.nix;
-}
diff --git a/lib/examples/file-utils.nix b/lib/examples/file-utils.nix
deleted file mode 100644
index 7d63c0d..0000000
--- a/lib/examples/file-utils.nix
+++ /dev/null
@@ -1,60 +0,0 @@
-{ lib, namespace, ... }:
-let
-  inherit (lib.${namespace}.file)
-    readFile
-    pathExists
-    safeImport
-    scanDir
-    getFile
-    importModulesRecursive
-    scanSystems
-    filterNixOSSystems
-    filterDarwinSystems
-    scanHomes
-    ;
-in
-{
-  # Example of reading a file
-  myFileContent = readFile ./example.txt;
-
-  # Example of checking if a file exists
-  fileExists = pathExists ./example.txt;
-
-  # Example of safely importing a file
-  myConfig = safeImport ./my-config.nix { };
-
-  # Example of scanning a directory
-  directoryContents = scanDir ./modules;
-
-  # Example of getting a file path relative to the flake root
-  flakeFile = getFile "flake.nix";
-
-  # Example of importing modules recursively
-  modules = importModulesRecursive ./modules;
-
-  # Example of scanning systems
-  allSystems = scanSystems ./systems;
-
-  # Example of filtering systems
-  nixosSystems = filterNixOSSystems allSystems;
-  darwinSystems = filterDarwinSystems allSystems;
-
-  # Example of scanning homes
-  allHomes = scanHomes ./homes;
-
-  # Example of using these functions together
-  nixosConfigurations = lib.mapAttrs' (
-    _name:
-    { system, hostname, ... }:
-    {
-      name = hostname;
-      value = lib.nixosSystem {
-        inherit system;
-        modules = [
-          { networking.hostName = hostname; }
-        ]
-        ++ importModulesRecursive ./modules/nixos;
-      };
-    }
-  ) nixosSystems;
-}
diff --git a/lib/examples/home-sops.nix b/lib/examples/home-sops.nix
deleted file mode 100644
index 7585e93..0000000
--- a/lib/examples/home-sops.nix
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  namespace,
-  ...
-}:
-let
-  inherit (lib.${namespace}.module) mkModule mkOpt;
-in
-mkModule {
-  name = "sops";
-  description = "SOPS secret management for home-manager";
-  options = {
-    defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
-
-    sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [ ] "SSH Key paths to use.";
-  };
-  config = {
-    home.packages = with pkgs; [
-      age
-      sops
-      ssh-to-age
-    ];
-
-    sops = {
-      inherit (config.${namespace}.sops) defaultSopsFile;
-      defaultSopsFormat = "yaml";
-
-      age = {
-        generateKey = true;
-        keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
-        sshKeyPaths = [
-          "${config.home.homeDirectory}/.ssh/id_ed25519"
-        ]
-        ++ config.${namespace}.sops.sshKeyPaths;
-      };
-    };
-  };
-}
diff --git a/lib/examples/reverseproxy.nix b/lib/examples/reverseproxy.nix
deleted file mode 100644
index 8b073f2..0000000
--- a/lib/examples/reverseproxy.nix
+++ /dev/null
@@ -1,117 +0,0 @@
-# Example usage of the reverse proxy utilities
-{ lib, namespace, ... }:
-let
-  inherit (lib.${namespace} - lib.reverseproxy)
-    mkReverseProxy
-    mkReverseProxies
-    templates
-    middlewares
-    urls
-    ;
-in
-{
-  # Example 1: Simple reverse proxy for a local service
-  simpleProxy = mkReverseProxy {
-    name = "myapp";
-    subdomain = "myapp";
-    url = "http://127.0.0.1:3000";
-  };
-
-  # Example 2: Authenticated service with custom middlewares
-  authProxy = mkReverseProxy {
-    name = "admin-panel";
-    subdomain = "admin";
-    url = "http://127.0.0.1:8080";
-    middlewares = middlewares.authBasic;
-  };
-
-  # Example 3: Container-based service
-  containerProxy = mkReverseProxy {
-    name = "nextcloud";
-    subdomain = "cloud";
-    url = urls.container "nextcloud" 80;
-    middlewares = middlewares.basic;
-  };
-
-  # Example 4: Multiple proxies at once
-  multipleProxies = mkReverseProxies [
-    {
-      name = "grafana";
-      subdomain = "grafana";
-      url = urls.localhost 3000;
-      middlewares = middlewares.authBasic;
-    }
-    {
-      name = "prometheus";
-      subdomain = "prometheus";
-      url = urls.localhost 9090;
-      middlewares = middlewares.internal;
-    }
-    {
-      name = "alertmanager";
-      subdomain = "alerts";
-      url = urls.localhost 9093;
-      middlewares = middlewares.authBasic;
-    }
-  ];
-
-  # Example 5: Using templates for common patterns
-  webappExample = templates.webapp {
-    name = "webapp";
-    subdomain = "app";
-    port = 8080;
-  };
-
-  authWebappExample = templates.authWebapp {
-    name = "secure-app";
-    subdomain = "secure";
-    port = 9000;
-  };
-
-  containerExample = templates.containerService {
-    name = "gitea";
-    subdomain = "git";
-    containerName = "gitea";
-    port = 3000;
-  };
-
-  internalExample = templates.internalService {
-    name = "internal-api";
-    subdomain = "api-internal";
-    port = 8000;
-  };
-
-  # Example 6: Custom domain and advanced configuration
-  customProxy = mkReverseProxy {
-    name = "custom-service";
-    subdomain = "custom";
-    url = "http://10.0.1.100:8080";
-    domain = "example.com";
-    priority = 20;
-    rule = "Host(`custom.example.com`) && PathPrefix(`/api`)";
-    middlewares = [
-      "crowdsec"
-      "whitelist-geoblock"
-      "rate-limit"
-    ];
-  };
-
-  # Example usage in a Traefik configuration:
-  #
-  # mjallen.services.traefik = {
-  #   enable = true;
-  #   extraServices = multipleProxies.extraServices;
-  #   extraRouters = multipleProxies.extraRouters;
-  # };
-  #
-  # Or for individual proxies:
-  #
-  # mjallen.services.traefik = {
-  #   enable = true;
-  #   extraServices = [ simpleProxy.service ];
-  #   extraRouters = [{
-  #     inherit (simpleProxy.router) subdomain entryPoints middlewares;
-  #     service = simpleProxy.router.service;
-  #   }];
-  # };
-}
diff --git a/lib/examples/sops.nix b/lib/examples/sops.nix
deleted file mode 100644
index 28e03d1..0000000
--- a/lib/examples/sops.nix
+++ /dev/null
@@ -1,45 +0,0 @@
-{
-  config,
-  lib,
-  namespace,
-  ...
-}:
-let
-  inherit (lib.${namespace}.module) mkModule mkOpt mkBoolOpt;
-in
-mkModule {
-  name = "sops";
-  description = "SOPS secret management";
-  options = {
-    defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
-
-    generateAgeKey = mkBoolOpt true "Whether to automatically generate an age key if one doesn't exist.";
-
-    ageKeyPath =
-      mkOpt (lib.types.nullOr lib.types.str) null
-        "Custom path to the age key file. If null, will use the default path.";
-
-    sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [
-      "/etc/ssh/ssh_host_ed25519_key"
-    ] "SSH Key paths to use.";
-
-    validateSopsFiles = mkBoolOpt false "Whether to validate that sops files exist.";
-  };
-  config = {
-    sops = {
-      inherit (config.${namespace}.sops) defaultSopsFile validateSopsFiles;
-
-      age = {
-        inherit (config.${namespace}.sops) generateAgeKey;
-
-        keyFile =
-          if config.${namespace}.sops.ageKeyPath != null then
-            config.${namespace}.sops.ageKeyPath
-          else
-            "${config.users.users.${config.${namespace}.user.name}.home}/.config/sops/age/keys.txt";
-
-        sshKeyPaths = config.${namespace}.sops.sshKeyPaths;
-      };
-    };
-  };
-}
diff --git a/lib/examples/system-utils.nix b/lib/examples/system-utils.nix
deleted file mode 100644
index 7949194..0000000
--- a/lib/examples/system-utils.nix
+++ /dev/null
@@ -1,132 +0,0 @@
-{ inputs, namespace, ... }:
-let
-  inherit (inputs.self.${namespace} - lib.system.common)
-    mkExtendedLib
-    mkNixpkgsConfig
-    mkHomeConfigs
-    mkHomeManagerConfig
-    mkSpecialArgs
-    ;
-in
-{
-  # Example of creating NixOS configurations
-  nixosConfigurations =
-    let
-      # Get all systems
-      allSystems = inputs.self.${namespace} - lib.file.scanSystems ../systems;
-
-      # Filter for NixOS systems
-      nixosSystems = inputs.self.${namespace} - lib.file.filterNixOSSystems allSystems;
-    in
-    inputs.nixpkgs.lib.mapAttrs' (
-      _name:
-      { system, hostname, ... }:
-      let
-        # Create extended lib with mjallen-lib
-        extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
-
-        # Find matching home configurations for this system
-        matchingHomes = mkHomeConfigs {
-          flake = inputs.self;
-          inherit system hostname;
-        };
-
-        # Create home-manager configuration
-        homeManagerConfig = mkHomeManagerConfig {
-          inherit
-            extendedLib
-            inputs
-            system
-            matchingHomes
-            ;
-          isNixOS = true;
-        };
-      in
-      {
-        name = hostname;
-        value = inputs.nixpkgs.lib.nixosSystem {
-          inherit system;
-
-          # Pass special arguments to modules
-          specialArgs = mkSpecialArgs {
-            inherit inputs hostname extendedLib;
-            username = "mjallen";
-          };
-
-          modules = [
-            # Set lib to extended lib
-            { _module.args.lib = extendedLib; }
-
-            # Configure nixpkgs
-            {
-              nixpkgs = {
-                inherit system;
-              }
-              // mkNixpkgsConfig inputs.self;
-            }
-
-            # Import home-manager module
-            inputs.home-manager.nixosModules.home-manager
-
-            # Auto-inject home configurations
-            homeManagerConfig
-
-            # Import all nixos modules recursively
-            ../${system}/${hostname}
-          ]
-          ++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/nixos);
-        };
-      }
-    ) nixosSystems;
-
-  # Example of creating home-manager configurations
-  homeConfigurations =
-    let
-      # Get all homes
-      allHomes = inputs.self.${namespace} - lib.file.scanHomes ../homes;
-    in
-    inputs.nixpkgs.lib.mapAttrs' (
-      _name:
-      {
-        system,
-        username,
-        hostname,
-        userAtHost,
-        path,
-        ...
-      }:
-      let
-        # Create extended lib with mjallen-lib
-        extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
-      in
-      {
-        name = userAtHost;
-        value = inputs.home-manager.lib.homeManagerConfiguration {
-          pkgs = import inputs.nixpkgs {
-            inherit system;
-            inherit ((mkNixpkgsConfig inputs.self)) config overlays;
-          };
-
-          extraSpecialArgs = {
-            inherit
-              inputs
-              hostname
-              username
-              system
-              ;
-            inherit (inputs) self;
-            lib = extendedLib;
-          };
-
-          modules = [
-            # Set lib to extended lib
-            { _module.args.lib = extendedLib; }
-
-            # Import the home configuration
-            path
-          ]
-          ++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/home);
-        };
-      }
-    ) allHomes;
-}
diff --git a/lib/module/default.nix b/lib/module/default.nix
index cf02a38..5a2c664 100644
--- a/lib/module/default.nix
+++ b/lib/module/default.nix
@@ -14,8 +14,6 @@ let
     mkDefault
     mkForce
     ;
-
-  base64Lib = import ../base64 { inherit inputs; };
 in
 rec {
 
@@ -26,7 +24,9 @@ rec {
       mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
     ) modules;
 
-  # Create a module with common options
+  # Create a NixOS module with standard options (enable, port, reverseProxy,
+  # firewall, user, postgresql, redis) and optional caller-supplied options and
+  # config.  All config is gated behind `cfg.enable`.
   mkModule =
     {
       name,
@@ -51,9 +51,6 @@ rec {
       defaultConfig = {
         # Caddy reverse proxy: when reverseProxy.enable = true, contribute this
         # service's named-matcher block into the shared wildcard virtual host.
-        # The TLS block stays in the caddy module itself; all services merge
-        # their handle blocks into the same "*.${domain}" extraConfig via the
-        # lines type (which concatenates automatically).
         services.caddy.virtualHosts."*.${cfg.reverseProxy.domain}" = lib.mkIf cfg.reverseProxy.enable {
           extraConfig = ''
             @${name} host ${fqdn}
@@ -79,20 +76,15 @@ rec {
           groups.${name} = { };
         };
 
-        systemd.services.${serviceName} = {
-          requires = [
-            "media-nas-main.mount"
-            # "openvpn-us.protonvpn.udp.service"
-          ];
-          after = lib.mkForce [
-            "media-nas-main.mount"
-            # "openvpn-us.protonvpn.udp.service"
-          ];
-          # serviceConfig = {
-          #   NetworkNamespacePath = lib.mkIf cfg.enableVpn "/run/netns/vpn";
-          #   # Consider also setting DNS *inside* the netns (see note below).
-          # };
-        };
+        # Ensure the service waits for the filesystem that hosts configDir and
+        # dataDir to be mounted before starting.  RequiresMountsFor is the
+        # idiomatic systemd way to express this: if the paths live on the root
+        # filesystem the directive is silently ignored, so it is safe on every
+        # host — not just the NAS.
+        systemd.services.${serviceName}.unitConfig.RequiresMountsFor = [
+          cfg.configDir
+          cfg.dataDir
+        ];
 
         services = {
           postgresql = lib.mkIf cfg.configureDb {
@@ -110,12 +102,6 @@ rec {
             port = cfg.redis.port;
           };
         };
-
-        # systemd.tmpfiles.rules = [
-        #   "d ${cfg.configDir} 0700 ${name} ${name} - -"
-        #   # "d ${cfg.configDir}/server-files 0775 ${name} ${name} - -"
-        #   # "d ${cfg.configDir}/user-files 0775 ${name} ${name} - -"
-        # ];
       };
     in
     { lib, ... }:
@@ -134,44 +120,42 @@ rec {
           options = {
             enable = lib.mkEnableOption description;
 
-            port = mkOpt types.int 80 "Port for ${name} to be hosted on";
+            port = mkOpt types.int 80 "Port for ${name} to listen on";
 
-            configDir = mkOpt types.str "/media/nas/main/appdata" "Path to the config dir";
+            configDir = mkOpt types.str "/var/lib/${name}" "Path to the config directory";
 
-            dataDir = mkOpt types.str "/media/nas/main" "Path to the data dir";
+            dataDir = mkOpt types.str "/var/lib/${name}/data" "Path to the data directory";
 
-            createUser = mkBoolOpt false "create a user for this module/service";
+            createUser = mkBoolOpt false "Create a dedicated system user for this service";
 
-            configureDb = mkBoolOpt false "Manage db for this service";
+            configureDb = mkBoolOpt false "Manage a PostgreSQL database for this service";
 
-            environmentFile = mkOpt types.str "" "Environment File";
+            environmentFile =
+              mkOpt (types.nullOr types.str) null
+                "Path to an environment file (EnvironmentFile=)";
 
-            puid = mkOpt types.str "911" "default user id";
+            puid = mkOpt types.str "911" "User ID for container-based services";
 
-            pgid = mkOpt types.str "1000" "default group id";
+            pgid = mkOpt types.str "100" "Group ID for container-based services";
 
-            timeZone = mkOpt types.str "America/Chicago" "default timezone";
+            timeZone = mkOpt types.str "UTC" "Timezone for container-based services";
 
-            listenAddress = mkOpt types.str "0.0.0.0" "Environment File";
+            listenAddress = mkOpt types.str "0.0.0.0" "Listen address";
 
-            openFirewall = mkBoolOpt true "Open the firewall";
-
-            enableVpn = mkBoolOpt true "Enable routing through VPN";
+            openFirewall = mkBoolOpt true "Open firewall ports for this service";
 
             redis = {
-              enable = lib.mkEnableOption "enable redis";
-
-              port = mkOpt types.int 80 "Port for ${name} redis to be hosted on";
+              enable = lib.mkEnableOption "a dedicated Redis server for this service";
+              port = mkOpt types.int 6379 "Redis port for ${name}";
             };
 
             hashedPassword =
-              mkOpt (types.nullOr types.str)
-                "$y$j9T$EkPXmsmIMFFZ.WRrBYCxS1$P0kwo6e4.WM5DsqUcEqWC3MrZp5KfCjxffraMFZWu06"
-                "Hashed password for code-server authentication";
+              mkOpt (types.nullOr types.str) null
+                "Hashed password (e.g. for web-based authentication)";
 
             extraEnvironment =
               mkOpt (types.attrsOf types.str) { }
-                "Extra environment variables for code-server";
+                "Extra environment variables passed to the service";
 
             reverseProxy = mkReverseProxyOpt name;
           }
@@ -181,58 +165,15 @@ rec {
       };
     };
 
-  # container
-  mkContainer =
-    {
-      name,
-      localAddress ? "127.0.0.1",
-      ports ? [ 80 ],
-      bindMounts ? { },
-      config ? { },
-    }:
-    { lib, ... }:
-    {
-      containers.${name} = {
-        inherit localAddress bindMounts;
-
-        config = config // {
-          networking = {
-            firewall = {
-              enable = true;
-              allowedTCPPorts = ports;
-            };
-            # Use systemd-resolved inside the container
-            # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
-            useHostResolvConf = lib.mkForce false;
-          };
-
-          services.resolved.enable = true;
-          system.stateVersion = "23.11";
-        };
-        autoStart = lib.mkDefault true;
-        privateNetwork = lib.mkDefault true;
-        hostAddress = lib.mkDefault "10.0.1.3";
-      };
-
-      networking = {
-        nat.forwardPorts = map (port: {
-          destination = lib.mkDefault "${localAddress}:${toString port}";
-          sourcePort = lib.mkDefault port;
-        }) ports;
-        firewall = {
-          allowedTCPPorts = ports;
-          allowedUDPPorts = ports;
-        };
-      };
-    };
-
-  # Migrated mjallen utilities
+  # ---------------------------------------------------------------------------
   # Option creation helpers
+  # ---------------------------------------------------------------------------
+
   mkOpt =
     type: default: description:
     mkOption { inherit type default description; };
 
-  mkOpt' = type: default: mkOpt type default null;
+  mkOpt' = type: default: mkOpt type default "";
 
   mkBoolOpt = mkOpt types.bool;
 
@@ -245,26 +186,28 @@ rec {
 
     domain = mkOpt types.str "mjallen.dev" "Base domain for the reverse proxy";
 
-    # Override the upstream URL if the backend is not on localhost at cfg.port.
-    # Leave empty to use http://127.0.0.1:<port> automatically.
     upstreamUrl =
       mkOpt (types.nullOr types.str) null
-        "Override upstream URL (e.g. for services on a different host). Defaults to http://127.0.0.1:<port>.";
+        "Override upstream URL (e.g. for a service on a different host). Defaults to http://127.0.0.1:<port>.";
 
-    # Extra Caddyfile directives inserted inside the virtual host block.
-    extraCaddyConfig = mkOpt types.lines "" "Extra Caddyfile directives for this virtual host block";
+    extraCaddyConfig = mkOpt types.lines "" "Extra Caddyfile directives inside this virtual host block";
   };
 
-  # Standard enable/disable patterns
+  # ---------------------------------------------------------------------------
+  # Convenience shorthands
+  # ---------------------------------------------------------------------------
+
   enabled = {
     enable = true;
   };
-
   disabled = {
     enable = false;
   };
 
+  # ---------------------------------------------------------------------------
   # String utilities
+  # ---------------------------------------------------------------------------
+
   capitalize =
     s:
     let
@@ -272,10 +215,16 @@ rec {
     in
     if len == 0 then "" else (toUpper (substring 0 1 s)) + (substring 1 len s);
 
+  # ---------------------------------------------------------------------------
   # Boolean utilities
+  # ---------------------------------------------------------------------------
+
   boolToNum = bool: if bool then 1 else 0;
 
+  # ---------------------------------------------------------------------------
   # Attribute manipulation utilities
+  # ---------------------------------------------------------------------------
+
   default-attrs = mapAttrs (_key: mkDefault);
 
   force-attrs = mapAttrs (_key: mkForce);
@@ -284,4 +233,3 @@ rec {
 
   nested-force-attrs = mapAttrs (_key: force-attrs);
 }
-// base64Lib
diff --git a/lib/reverseproxy/default.nix b/lib/reverseproxy/default.nix
deleted file mode 100644
index 0170150..0000000
--- a/lib/reverseproxy/default.nix
+++ /dev/null
@@ -1,220 +0,0 @@
-{ inputs }:
-let
-  inherit (inputs.nixpkgs.lib)
-    listToAttrs
-    nameValuePair
-    ;
-in
-rec {
-  # Create a service configuration for Traefik
-  mkService =
-    {
-      name,
-      url,
-      loadBalancer ? { },
-    }:
-    {
-      inherit name url;
-      config = {
-        loadBalancer = {
-          servers = [ { inherit url; } ];
-        }
-        // loadBalancer;
-      };
-    };
-
-  # Create a router configuration for Traefik
-  mkRouter =
-    {
-      subdomain,
-      domain ? "mjallen.dev",
-      service,
-      entryPoints ? [ "websecure" ],
-      middlewares ? [
-        "crowdsec"
-        "whitelist-geoblock"
-      ],
-      priority ? null,
-      rule ? null,
-      tls ? {
-        certResolver = "letsencrypt";
-      },
-    }:
-    {
-      inherit
-        subdomain
-        service
-        entryPoints
-        middlewares
-        ;
-      config = {
-        inherit
-          entryPoints
-          service
-          middlewares
-          tls
-          ;
-        rule = if rule != null then rule else "Host(`${subdomain}.${domain}`)";
-      }
-      // (if priority != null then { inherit priority; } else { });
-    };
-
-  # Create both service and router for a simple reverse proxy setup
-  mkReverseProxy =
-    {
-      name,
-      subdomain,
-      url,
-      domain ? "mjallen.dev",
-      entryPoints ? [ "websecure" ],
-      middlewares ? [
-        "crowdsec"
-        "whitelist-geoblock"
-      ],
-      priority ? null,
-      rule ? null,
-      tls ? {
-        certResolver = "letsencrypt";
-      },
-      loadBalancer ? { },
-    }:
-    {
-      service = mkService {
-        inherit name url loadBalancer;
-      };
-      router = mkRouter {
-        inherit
-          subdomain
-          domain
-          entryPoints
-          middlewares
-          priority
-          rule
-          tls
-          ;
-        service = name;
-      };
-    };
-
-  # Convert a list of services to the format expected by Traefik module
-  servicesToConfig =
-    services: listToAttrs (map (service: nameValuePair service.name service.config) services);
-
-  # Convert a list of routers to the format expected by Traefik module
-  routersToConfig =
-    routers: listToAttrs (map (router: nameValuePair router.subdomain router.config) routers);
-
-  # Helper to create multiple reverse proxies at once
-  mkReverseProxies =
-    proxies:
-    let
-      results = map mkReverseProxy proxies;
-      services = map (result: result.service) results;
-      routers = map (result: result.router) results;
-    in
-    {
-      services = servicesToConfig services;
-      routers = routersToConfig routers;
-      extraServices = services;
-      extraRouters = map (router: {
-        inherit (router) subdomain entryPoints middlewares;
-        service = router.service;
-      }) routers;
-    };
-
-  # Common middleware configurations
-  middlewares = {
-    # Authentication middleware
-    auth = [ "authentik" ];
-
-    # Basic security (default)
-    basic = [
-      "crowdsec"
-      "whitelist-geoblock"
-    ];
-
-    # Internal only access
-    internal = [
-      "crowdsec"
-      "whitelist-geoblock"
-      "internal-ipallowlist"
-    ];
-
-    # WebSocket support
-    websocket = [
-      "crowdsec"
-      "whitelist-geoblock"
-      "onlyoffice-websocket"
-    ];
-
-    # Authenticated with basic security
-    authBasic = [
-      "crowdsec"
-      "whitelist-geoblock"
-      "authentik"
-    ];
-  };
-
-  # Common service URL builders
-  urls = {
-    # Local container service
-    container =
-      containerName: port: "http://\${config.containers.${containerName}.localAddress}:${toString port}";
-
-    # Local host service
-    localhost = port: "http://127.0.0.1:${toString port}";
-
-    # Network service
-    network = ip: port: "http://${ip}:${toString port}";
-
-    # Server IP service (using your server IP pattern)
-    server = port: "http://\${serverIp}:${toString port}";
-  };
-
-  # Pre-configured reverse proxy templates
-  templates = {
-    # Standard web application
-    webapp =
-      { port, ... }@args:
-      mkReverseProxy (
-        {
-          url = urls.localhost port;
-          middlewares = middlewares.basic;
-        }
-        // args
-      );
-
-    # Authenticated web application
-    authWebapp =
-      { port, ... }@args:
-      mkReverseProxy (
-        {
-          url = urls.localhost port;
-          middlewares = middlewares.authBasic;
-        }
-        // args
-      );
-
-    # Container-based service
-    containerService =
-      { containerName, port, ... }@args:
-      mkReverseProxy (
-        {
-          url = urls.container containerName port;
-          middlewares = middlewares.basic;
-        }
-        // args
-      );
-
-    # Internal-only service
-    internalService =
-      { port, ... }@args:
-      mkReverseProxy (
-        {
-          url = urls.localhost port;
-          middlewares = middlewares.internal;
-        }
-        // args
-      );
-  };
-}
diff --git a/lib/system/common.nix b/lib/system/common.nix
deleted file mode 100644
index c40a9c2..0000000
--- a/lib/system/common.nix
+++ /dev/null
@@ -1,103 +0,0 @@
-{ inputs, namespace }:
-let
-  inherit (inputs.nixpkgs.lib) filterAttrs mapAttrs';
-in
-{
-  mkExtendedLib =
-    flake: nixpkgs:
-    nixpkgs.lib.extend (
-      _final: _prev: {
-        mjallen = flake.${namespace} - lib;
-      }
-    );
-
-  mkNixpkgsConfig = flake: {
-    overlays = builtins.attrValues flake.overlays;
-    config = {
-      allowAliases = false;
-      allowUnfree = true;
-      permittedInsecurePackages = [
-        # Add any permitted insecure packages here
-        "mbedtls-2.28.10"
-      ];
-    };
-  };
-
-  mkHomeConfigs =
-    {
-      flake,
-      system,
-      hostname,
-    }:
-    let
-      inherit (flake.${namespace} - lib.file) scanHomes;
-      homesPath = ../../homes;
-      allHomes = scanHomes homesPath;
-    in
-    filterAttrs (
-      _name: homeConfig: homeConfig.system == system && homeConfig.hostname == hostname
-    ) allHomes;
-
-  mkHomeManagerConfig =
-    {
-      extendedLib,
-      inputs,
-      system,
-      matchingHomes,
-      isNixOS ? true,
-    }:
-    if matchingHomes != { } then
-      {
-        home-manager = {
-          useGlobalPkgs = true;
-          useUserPackages = true;
-          extraSpecialArgs = {
-            inherit inputs system;
-            inherit (inputs) self;
-            lib = extendedLib;
-          };
-          sharedModules = [
-            { _module.args.lib = extendedLib; }
-          ]
-          ++ (extendedLib.${namespace}.file.importModulesRecursive ../../modules/home);
-          users = mapAttrs' (_name: homeConfig: {
-            name = homeConfig.username;
-            value = {
-              imports = [ homeConfig.path ];
-              home = {
-                inherit (homeConfig) username;
-                homeDirectory = inputs.nixpkgs.lib.mkDefault (
-                  if isNixOS then "/home/${homeConfig.username}" else "/Users/${homeConfig.username}"
-                );
-              };
-            }
-            // (
-              if isNixOS then
-                {
-                  _module.args.username = homeConfig.username;
-                }
-              else
-                { }
-            );
-          }) matchingHomes;
-        };
-      }
-    else
-      { };
-
-  mkSpecialArgs =
-    {
-      inputs,
-      hostname,
-      username,
-      extendedLib,
-    }:
-    {
-      inherit inputs hostname username;
-      inherit (inputs) self;
-      lib = extendedLib;
-      namespace = "mjallen";
-      format = "system";
-      host = hostname;
-    };
-}
diff --git a/lib/system/default.nix b/lib/system/default.nix
deleted file mode 100644
index 193c703..0000000
--- a/lib/system/default.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{ inputs }:
-{
-  # Common utilities used by system builders
-  common = import ./common.nix { inherit inputs; };
-}
diff --git a/modules/nixos/services/grafana/default.nix b/modules/nixos/services/grafana/default.nix
index d6f1d20..525f5b2 100755
--- a/modules/nixos/services/grafana/default.nix
+++ b/modules/nixos/services/grafana/default.nix
@@ -77,7 +77,7 @@ let
             };
           };
 
-          dataDir = "/media/nas/main/nix-app-data/grafana";
+          dataDir = "${cfg.configDir}/grafana";
 
           provision = {
             enable = true;
diff --git a/modules/nixos/services/owncloud/default.nix b/modules/nixos/services/owncloud/default.nix
index dd5eeb0..c29c787 100755
--- a/modules/nixos/services/owncloud/default.nix
+++ b/modules/nixos/services/owncloud/default.nix
@@ -34,12 +34,12 @@ in
 
     dataPath = mkOption {
       type = types.str;
-      default = "/media/nas/main/ocis";
+      default = "/var/lib/ocis";
     };
 
     configPath = mkOption {
       type = types.str;
-      default = "/media/nas/main/nix-app-data/ocis";
+      default = "/var/lib/ocis/config";
     };
 
     puid = mkOption {
diff --git a/modules/nixos/services/your-spotify/options.nix b/modules/nixos/services/your-spotify/options.nix
index dea5d89..88f86b4 100755
--- a/modules/nixos/services/your-spotify/options.nix
+++ b/modules/nixos/services/your-spotify/options.nix
@@ -36,7 +36,7 @@ with lib;
 
     configPath = mkOption {
       type = types.str;
-      default = "/media/nas/main/nix-app-data/your_spotify";
+      default = "/var/lib/your-spotify";
     };
 
     puid = mkOption {
@@ -46,12 +46,12 @@ with lib;
 
     pgid = mkOption {
       type = types.str;
-      default = "1000";
+      default = "100";
     };
 
     timeZone = mkOption {
       type = types.str;
-      default = "America/Chicago";
+      default = "UTC";
     };
   };
 }
diff --git a/systems/x86_64-linux/jallen-nas/default.nix b/systems/x86_64-linux/jallen-nas/default.nix
index 0a6513c..c015414 100755
--- a/systems/x86_64-linux/jallen-nas/default.nix
+++ b/systems/x86_64-linux/jallen-nas/default.nix
@@ -11,6 +11,7 @@ in
 {
   imports = [
     ./boot.nix
+    ./nas-defaults.nix
     ./apps.nix
     ./disabled.nix
     # ./nas-pool.nix
@@ -18,7 +19,6 @@ in
     ./services.nix
     ./sops.nix
     ./vpn.nix
-    # testcontainer
   ];
 
   services.kmscon = disabled;
diff --git a/systems/x86_64-linux/jallen-nas/nas-defaults.nix b/systems/x86_64-linux/jallen-nas/nas-defaults.nix
new file mode 100644
index 0000000..6341c76
--- /dev/null
+++ b/systems/x86_64-linux/jallen-nas/nas-defaults.nix
@@ -0,0 +1,86 @@
+# NAS-wide defaults for all mkModule services.
+#
+# Every service's configDir and dataDir default to paths on the NAS bcachefs
+# pool.  Setting them here via lib.mkDefault means individual service
+# declarations in apps.nix only need to override when they deviate from the
+# convention, keeping apps.nix concise.
+#
+# The companion RequiresMountsFor in mkModule uses these paths to derive the
+# correct systemd mount dependency automatically — no service needs to hardcode
+# "media-nas-main.mount" by name.
+{ lib, namespace, ... }:
+let
+  appdata = "/media/nas/main/appdata";
+  data = "/media/nas/main";
+
+  svcDefault = name: {
+    ${namespace}.services.${name} = {
+      configDir = lib.mkDefault appdata;
+      dataDir = lib.mkDefault data;
+    };
+  };
+in
+{
+  # Bespoke services that define their own path options (not via mkModule).
+  # Set NAS-specific paths here so the module defaults stay generic.
+  ${namespace}.services.your_spotify.configPath = lib.mkDefault "${appdata}/your_spotify";
+  ${namespace}.services.ocis = {
+    dataPath = lib.mkDefault "${data}/ocis";
+    configPath = lib.mkDefault "${appdata}/ocis";
+  };
+
+  imports = map svcDefault [
+    "actual"
+    "ai"
+    "arrs"
+    "attic"
+    "authentik"
+    "authentikRac"
+    "booklore"
+    "caddy"
+    "calibre"
+    "calibre-web"
+    "code-server"
+    "collabora"
+    "coturn"
+    "crowdsec"
+    "dispatcharr"
+    "free-games-claimer"
+    "gitea"
+    "glance"
+    "glances"
+    "grafana"
+    "guacd"
+    "headscale"
+    "immich"
+    "jellyfin"
+    "jellyseerr"
+    "lubelogger"
+    "manyfold"
+    "matrix"
+    "minecraft"
+    "mongodb"
+    "nebula"
+    "nebula-lighthouse"
+    "netbootxyz"
+    "nextcloud"
+    "ntfy"
+    "onlyoffice"
+    "opencloud"
+    "orca-slicer"
+    "paperless"
+    "paperless-ai"
+    "protonmail-bridge"
+    "restic"
+    "sparky-fitness"
+    "sparky-fitness-server"
+    "sparky-fitness-db"
+    "sunshine"
+    "tdarr"
+    "termix"
+    "tunarr"
+    "unmanic"
+    "uptime-kuma"
+    "wyoming"
+  ];
+}
