{ lib, pkgs, ... }: let nasData = "/media/nas/main"; in { systemd.network.wait-online.enable = false; # Force tailscaled to use nftables (Critical for clean nftables-only systems) # This avoids the "iptables-compat" translation layer issues. systemd.services.tailscaled.serviceConfig.Environment = [ "TS_DEBUG_FIREWALL_MODE=nftables" ]; networking.nftables.enable = true; boot.initrd.systemd.network.wait-online.enable = false; # Services configs services = { tailscale = { enable = true; openFirewall = true; useRoutingFeatures = "server"; extraUpFlags = [ "--advertise-exit-node" "--accept-dns=false" "--advertise-routes=10.0.1.0/24" "--hostname=jallen-nas" ]; extraSetFlags = [ "--advertise-exit-node" "--hostname=jallen-nas" "--webclient" ]; # authKeyFile = "/media/nas/main/nix-app-data/tailscale/auth"; }; postgresql = { enable = true; package = pkgs.postgresql_16; enableTCPIP = true; dataDir = "${nasData}/databases/postgresql"; ensureDatabases = [ "authentik" "homeassistant" "nextcloud" "onlyoffice" "synapse" "sparkyfitness" ]; ensureUsers = [ { name = "authentik"; ensureDBOwnership = true; } { name = "homeassistant"; ensureDBOwnership = true; } { name = "nextcloud"; ensureDBOwnership = true; } { name = "onlyoffice"; ensureDBOwnership = true; } { name = "synapse"; ensureDBOwnership = true; } { name = "sparkyfitness"; ensureDBOwnership = true; } ]; # pg_hba.conf — use lib.mkForce to replace the module defaults entirely. # # Connection matrix: # postgres (admin) — Unix socket, peer (OS user postgres = DB user postgres) # authentik — Unix socket, peer (OS user authentik = DB user authentik) # nextcloud — Unix socket, peer (OS user nextcloud = DB user nextcloud) # homeassistant — Unix socket, peer via identMap (OS user hass → DB user homeassistant) # synapse — Unix socket, peer via identMap (OS user matrix-synapse → DB user synapse) # onlyoffice — Unix socket, peer (OS user onlyoffice = DB user onlyoffice) [disabled] # sparkyfitness — Podman container TCP (10.88.0.0/16), scram-sha-256 authentication = lib.mkForce '' # TYPE DATABASE USER ADDRESS METHOD # All local Unix socket connections use peer auth (with identMap for mismatched names) local all all peer map=system # Podman container network — sparkyfitness server connects via host LAN IP host sparkyfitness sparkyfitness 10.88.0.0/16 scram-sha-256 ''; # identMap — maps OS usernames to PostgreSQL usernames for peer auth. # The catch-all regex rule (/^(.*)$ \1) allows any OS user whose name matches # their DB user directly (authentik, nextcloud, onlyoffice, postgres). # Explicit entries cover the mismatches. identMap = lib.mkForce '' # MAPNAME OS-USERNAME DB-USERNAME system hass homeassistant system matrix-synapse synapse system /^(.*)$ \1 ''; # TODO: set sparkyfitness password declaratively via ensureUsers.*.ensureClauses.password # once the SCRAM-SHA-256 hash is stored in SOPS (jallen-nas/sparky-fitness/db-password). # The old initialScript has been removed — it only ran on first DB init and is now stale. }; mysql = { enable = true; package = pkgs.mariadb; # explicit MariaDB package dataDir = "${nasData}/databases/mariadb"; settings.mysqld = { bind-address = "0.0.0.0"; port = 3306; }; initialDatabases = [ { name = "booklore"; } ]; ensureUsers = [ { name = "booklore"; ensurePermissions = { "database.*" = "ALL PRIVILEGES"; "*.*" = "SELECT, LOCK TABLES"; }; } ]; }; redis = { servers = { authentik = { enable = true; port = 6379; }; ccache = { enable = true; port = 6363; bind = "0.0.0.0"; openFirewall = true; extraParams = [ "--protected-mode no" ]; }; manyfold = { enable = true; port = 6380; }; onlyoffice = { enable = true; port = 6381; }; }; }; }; }