nixos-config/modules/podman-postgresql.nix

131 lines
4 KiB
Nix
Raw Normal View History

2023-06-26 14:48:00 +02:00
{ config, lib, pkgs, ... }:
with lib;
let
cfgs = config.services.podman-postgresql;
conf = import ./vars.nix;
2023-06-26 14:48:00 +02:00
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";
};
backupInterval = mkOption {
description = "The interval to backup the database";
type = types.str;
default = "hourly";
example = "daily";
};
backupRetention = mkOption {
description = "The amount of backups to keep.";
type = types.int;
default = 28;
example = "2";
};
2023-06-26 14:48:00 +02:00
};
}));
};
};
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 = {
2023-06-26 15:46:10 +02:00
TZ = "Europe/Berlin";
2023-06-26 14:48:00 +02:00
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}"
];
extraOptions = conf.podman.extraOptions ++ [
"--health-cmd=pg_isready -d ${cfg.database} -U ${cfg.user}"
"--health-start-period=10s"
];
2023-06-26 14:48:00 +02:00
};
}) 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 =
let
retention = (toString cfg.backupRetention);
in
"${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 && find ${cfg.backupPath}/${cfg.database} -type f | sort | head -n -${retention} | xargs rm -v'" ;
2023-06-26 14:48:00 +02:00
Type = "oneshot";
};
};
timers."podman-postgresql-${cfg.database}-backup" = {
timerConfig = {
OnCalendar = cfg.backupInterval;
2023-06-26 14:48:00 +02:00
};
wantedBy = [ "podman-postgresql-${cfg.database}.service" ];
};
}) cfgs);
};
}
# vim: set et ts=2 sw=2 ai: