{ config, lib, pkgs, ... }: let listNames = config.syscfg.server.db; containerNames = lib.mapAttrsToList (name: cfg: name) (lib.filterAttrs (name: cfg: cfg.db or false) config.syscfg.server.containers); allApps = lib.unique (listNames ++ containerNames); in { config = lib.mkIf ( builtins.length allApps > 0) { services.postgresql = { enable = true; ensureDatabases = map (name: "${name}_db") allApps; ensureUsers = map (name: { name = "${name}_user"; }) allApps; }; services.postgresqlBackup = { enable = true; location = "/var/lib/postgresql/backups"; startAt = "*-*-* 04:00:00"; # Runs every day at 4 AM backupAll = true; # Backs up all databases and roles }; # systemd.services.postgresql.postStart = lib.mkAfter '' # PSQL="${pkgs.postgresql}/bin/psql" # ${lib.concatMapStringsSep "\n" (name: '' # $PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = '${name}_user'" | grep -q 1 || \ # $PSQL -tAc "CREATE ROLE ${name}_user WITH LOGIN;" # $PSQL -tAc "ALTER DATABASE ${name}_db OWNER TO ${name}_user;" # if [ -f "${config.sops.secrets."${name}_pass".path}" ]; then # PASS=$(cat "${config.sops.secrets."${name}_pass".path}") # $PSQL -tAc "ALTER USER ${name}_user WITH PASSWORD '$PASS';" # fi # '') allApps} # ''; systemd.services.init-db-permissions = { description = "Set DB passwords and ownership after Postgres is ready"; after = [ "postgresql.service" ]; requires = [ "postgresql.service" ]; partOf = [ "postgresql.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; User = "postgres"; # Runs as postgres user directly RemainAfterExit = true; ExecStartPre = "${pkgs.coreutils}/bin/sleep 2"; }; script = '' PSQL="${pkgs.postgresql}/bin/psql" ${lib.concatMapStringsSep "\n" (name: '' until $PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = '${name}_user'" | grep -q 1; do echo "Waiting for user ${name}_user..." sleep 1 done $PSQL -tAc "ALTER DATABASE ${name}_db OWNER TO ${name}_user;" if [ -f "${config.sops.secrets."${lib.toUpper name}".path}" ]; then PASS=''$(grep "^DB_PASSWORD=" "${config.sops.secrets."${lib.toUpper name}".path}" | cut -d'=' -f2-) $PSQL -tAc "ALTER USER ${name}_user WITH PASSWORD '$PASS';" fi '') allApps} ''; }; }; }