diff --git a/modules/podman-postgresql.nix b/modules/podman-postgresql.nix new file mode 100644 index 0000000..3075560 --- /dev/null +++ b/modules/podman-postgresql.nix @@ -0,0 +1,106 @@ +{ config, lib, pkgs, ... }: +with lib; + +let cfgs = config.services.podman-postgresql; + +in +{ + + options = { + services.podman-postgresql = mkOption { + description = mdDoc "Configure a single database postgresql instance running in podman."; + default = {}; + type = types.attrsOf (types.submodule ({ config, ... }: { + options = let + name = config._module.args.name; + in + { + enable = mkEnableOption (mdDoc "podman-postgresql"); + + image = mkOption { + description = mdDoc "The postgresql image to use."; + type = types.str; + default = "docker.io/library/postgres:alpine"; + example = "docker.io/library/postgres:15-alpine"; + }; + + database = mkOption { + description = "The name of the database to be created."; + type = types.str; + default = name; + }; + + user = mkOption { + description = "The owner of the database."; + type = types.str; + default = name; + }; + + passwordFile = mkOption { + description = "The password file for the database user."; + type = types.path; + }; + + port = mkOption { + description = "The port to serve postgresql on the host."; + type = types.int; + example = 54320; + }; + + backupPath = mkOption { + description = "The path to backup the database to."; + type = types.str; + default = "/var/backup/postgresql"; + }; + + }; + })); + }; + }; + + config = mkIf (any (cfg: cfg.enable) (attrValues cfgs)) { + + virtualisation.oci-containers.containers = mkMerge (mapAttrsToList (_: cfg: { + "postgresql-${cfg.database}" = { + image = cfg.image; + ports = [ "${(toString cfg.port)}:5432" ]; + environment = { + POSTGRES_USER = cfg.user; + POSTGRES_DB = cfg.database; + POSTGRES_PASSWORD_FILE = cfg.passwordFile; + }; + volumes = [ + "/var/lib/postgresql/${cfg.database}:/var/lib/postgresql/data" + "${cfg.passwordFile}:${cfg.passwordFile}" + ]; + }; + }) cfgs); + + system.activationScripts = mkMerge (mapAttrsToList (_: cfg: { + "makePsql${cfg.database}Dirs" = lib.stringAfter [ "var" ] '' + mkdir -p "/var/lib/postgresql/${cfg.database}" "${cfg.backupPath}/${cfg.database}" + ''; + }) cfgs); + + + systemd = mkMerge (mapAttrsToList (_: cfg: { + services."podman-postgresql-${cfg.database}-backup" = { + description = "Backup of ${cfg.database} database"; + requisite = [ "podman-postgresql-${cfg.database}.service" ]; + serviceConfig = { + ExecStart = "${pkgs.bash}/bin/bash -c '${pkgs.podman}/bin/podman exec postgresql-${cfg.database} pg_dumpall -c -U ${cfg.user} | ${pkgs.zstd}/bin/zstd -o ${cfg.backupPath}/${cfg.database}/\$(${pkgs.coreutils}/bin/date +%%F_%%R).sql.zst'" ; + Type = "oneshot"; + }; + }; + timers."podman-postgresql-${cfg.database}-backup" = { + timerConfig = { + OnCalendar = "hourly"; + }; + wantedBy = [ "podman-postgresql-${cfg.database}.service" ]; + }; + }) cfgs); + + }; + +} +# vim: set et ts=2 sw=2 ai: