1 { config, lib, pkgs, ... }:
7 cfg = config.services.postgresqlBackup;
9 postgresqlBackupService = db: dumpCmd:
16 compressSuffix = getAttr cfg.compression compressSuffixes;
18 compressCmd = getAttr cfg.compression {
20 "gzip" = "${pkgs.gzip}/bin/gzip -c -${toString cfg.compressionLevel}";
21 "zstd" = "${pkgs.zstd}/bin/zstd -c -${toString cfg.compressionLevel}";
24 mkSqlPath = prefix: suffix: "${cfg.location}/${db}${prefix}.sql${suffix}";
25 curFile = mkSqlPath "" compressSuffix;
26 prevFile = mkSqlPath ".prev" compressSuffix;
27 prevFiles = map (mkSqlPath ".prev") (attrValues compressSuffixes);
28 inProgressFile = mkSqlPath ".in-progress" compressSuffix;
32 description = "Backup of ${db} database(s)";
34 requires = [ "postgresql.service" ];
36 path = [ pkgs.coreutils config.services.postgresql.package ];
41 umask 0077 # ensure backup is only readable by postgres user
43 if [ -e ${curFile} ]; then
44 rm -f ${toString prevFiles}
45 mv ${curFile} ${prevFile}
52 mv ${inProgressFile} ${curFile}
60 startAt = cfg.startAt;
66 (mkRemovedOptionModule [ "services" "postgresqlBackup" "period" ] ''
67 A systemd timer is now used instead of cron.
68 The starting time can be configured via <literal>services.postgresqlBackup.startAt</literal>.
73 services.postgresqlBackup = {
74 enable = mkEnableOption (lib.mdDoc "PostgreSQL dumps");
77 default = "*-*-* 01:15:00";
78 type = with types; either (listOf str) str;
79 description = lib.mdDoc ''
80 This option defines (see `systemd.time` for format) when the
81 databases should be dumped.
82 The default is to update at 01:15 (at night) every day.
86 backupAll = mkOption {
87 default = cfg.databases == [];
88 defaultText = literalExpression "services.postgresqlBackup.databases == []";
89 type = lib.types.bool;
90 description = lib.mdDoc ''
91 Backup all databases using pg_dumpall.
92 This option is mutual exclusive to
93 `services.postgresqlBackup.databases`.
94 The resulting backup dump will have the name all.sql.gz.
95 This option is the default if no databases are specified.
99 databases = mkOption {
101 type = types.listOf types.str;
102 description = lib.mdDoc ''
103 List of database names to dump.
107 location = mkOption {
108 default = "/var/backup/postgresql";
110 description = lib.mdDoc ''
111 Path of directory where the PostgreSQL database dumps will be placed.
115 pgdumpOptions = mkOption {
116 type = types.separatedString " ";
118 description = lib.mdDoc ''
119 Command line options for pg_dump. This options is not used
120 if `config.services.postgresqlBackup.backupAll` is enabled.
121 Note that config.services.postgresqlBackup.backupAll is also active,
122 when no databases where specified.
126 compression = mkOption {
127 type = types.enum ["none" "gzip" "zstd"];
129 description = lib.mdDoc ''
130 The type of compression to use on the generated database dump.
134 compressionLevel = mkOption {
135 type = types.ints.between 1 19;
137 description = lib.mdDoc ''
138 The compression level used when compression is enabled.
139 gzip accepts levels 1 to 9. zstd accepts levels 1 to 19.
150 assertion = cfg.backupAll -> cfg.databases == [];
151 message = "config.services.postgresqlBackup.backupAll cannot be used together with config.services.postgresqlBackup.databases";
154 assertion = cfg.compression == "none" ||
155 (cfg.compression == "gzip" && cfg.compressionLevel >= 1 && cfg.compressionLevel <= 9) ||
156 (cfg.compression == "zstd" && cfg.compressionLevel >= 1 && cfg.compressionLevel <= 19);
157 message = "config.services.postgresqlBackup.compressionLevel must be set between 1 and 9 for gzip and 1 and 19 for zstd";
162 systemd.tmpfiles.rules = [
163 "d '${cfg.location}' 0700 postgres - - -"
166 (mkIf (cfg.enable && cfg.backupAll) {
167 systemd.services.postgresqlBackup =
168 postgresqlBackupService "all" "pg_dumpall";
170 (mkIf (cfg.enable && !cfg.backupAll) {
171 systemd.services = listToAttrs (map (db:
173 cmd = "pg_dump ${cfg.pgdumpOptions} ${db}";
175 name = "postgresqlBackup-${db}";
176 value = postgresqlBackupService db cmd;