configure borg production backups

This commit is contained in:
Yisroel Baum 2026-08-17 20:49:30 +03:00
parent 22a01e0c04
commit 9cb10a96fd
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9

View file

@ -16,9 +16,25 @@ let
uploadLimits = import ./upload-limits.nix; uploadLimits = import ./upload-limits.nix;
storagePath = "${cfg.stateDir}/storage"; storagePath = "${cfg.stateDir}/storage";
cachePath = "${cfg.cacheDir}/bootstrap-cache"; cachePath = "${cfg.cacheDir}/bootstrap-cache";
backupDir = "/var/backup/rabbi-gerzi";
databaseDumpPath = "${backupDir}/rabbi-gerzi.dump";
phpFpmWasActivePath = "/root/.cache/borg/rabbi-gerzi-phpfpm-was-active";
setupService = "rabbi-gerzi-setup"; setupService = "rabbi-gerzi-setup";
phpfpmService = "phpfpm-${poolName}"; phpfpmService = "phpfpm-${poolName}";
databaseDumpCommand = lib.concatStringsSep " " [
"${config.services.postgresql.package}/bin/pg_dump"
"--format=custom"
"--dbname=${cfg.database.name}"
];
secretFileOption =
description:
lib.mkOption {
type = lib.types.path;
inherit description;
};
appEnvironment = { appEnvironment = {
APP_ENV = "production"; APP_ENV = "production";
APP_DEBUG = "false"; APP_DEBUG = "false";
@ -55,6 +71,11 @@ in
options.services.rabbi-gerzi = { options.services.rabbi-gerzi = {
enable = lib.mkEnableOption "the Rabbi Gerzi application"; enable = lib.mkEnableOption "the Rabbi Gerzi application";
secretFiles = {
borgPassphrase = secretFileOption "Borg repository passphrase file.";
borgPrivateKey = secretFileOption "Borg repository SSH private key file.";
};
user = lib.mkOption { user = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "rabbi-gerzi"; default = "rabbi-gerzi";
@ -221,21 +242,85 @@ in
]; ];
}; };
systemd.tmpfiles.rules = map makeDirectoryRule [ services.borgbackup.jobs.rabbi-gerzi = {
cfg.stateDir paths = [
cfg.cacheDir cfg.stateDir
storagePath databaseDumpPath
"${storagePath}/app" ];
"${storagePath}/app/private" repo = "ssh://mgjjruz9@mgjjruz9.repo.borgbase.com/./repo";
"${storagePath}/app/public" user = "root";
"${storagePath}/framework" group = "root";
"${storagePath}/framework/cache" encryption = {
"${storagePath}/framework/cache/data" mode = "repokey-blake2";
"${storagePath}/framework/sessions" passCommand = "${pkgs.coreutils}/bin/cat ${cfg.secretFiles.borgPassphrase}";
"${storagePath}/framework/views" };
"${storagePath}/logs" doInit = true;
cachePath compression = "auto,zstd";
]; startAt = "*-*-* 05:15:00";
persistentTimer = true;
prune.keep = {
daily = 7;
weekly = 4;
monthly = 6;
};
readWritePaths = [ backupDir ];
environment.BORG_RSH = lib.concatStringsSep " " [
"ssh"
"-i ${cfg.secretFiles.borgPrivateKey}"
"-o IdentitiesOnly=yes"
"-o BatchMode=yes"
"-o StrictHostKeyChecking=accept-new"
"-o UserKnownHostsFile=/root/.config/borg/known_hosts"
];
preHook = ''
phpFpmWasActive=${phpFpmWasActivePath}
dumpFile=${databaseDumpPath}
if ${pkgs.systemd}/bin/systemctl is-active --quiet ${phpfpmService}.service; then
touch "$phpFpmWasActive"
${pkgs.systemd}/bin/systemctl stop ${phpfpmService}.service
else
rm -f "$phpFpmWasActive"
fi
rm -f "$dumpFile"
umask 077
${lib.getExe' pkgs.su "su"} \
-s ${pkgs.runtimeShell} \
${config.services.postgresql.superUser} \
-c '${databaseDumpCommand}' \
> "$dumpFile"
'';
postHook = ''
phpFpmWasActive=${phpFpmWasActivePath}
dumpFile=${databaseDumpPath}
rm -f "$dumpFile"
if [ -e "$phpFpmWasActive" ]; then
${pkgs.systemd}/bin/systemctl start ${phpfpmService}.service
rm -f "$phpFpmWasActive"
fi
'';
};
systemd.tmpfiles.rules =
(map makeDirectoryRule [
cfg.stateDir
cfg.cacheDir
storagePath
"${storagePath}/app"
"${storagePath}/app/private"
"${storagePath}/app/public"
"${storagePath}/framework"
"${storagePath}/framework/cache"
"${storagePath}/framework/cache/data"
"${storagePath}/framework/sessions"
"${storagePath}/framework/views"
"${storagePath}/logs"
cachePath
])
++ [ "d ${backupDir} 0700 root root - -" ];
services.phpfpm.pools.${poolName} = { services.phpfpm.pools.${poolName} = {
inherit (cfg) user group; inherit (cfg) user group;
@ -289,6 +374,7 @@ in
environment = appEnvironment; environment = appEnvironment;
serviceConfig = { serviceConfig = {
EnvironmentFile = cfg.backend.environmentFile; EnvironmentFile = cfg.backend.environmentFile;
KillSignal = "SIGQUIT";
ReadWritePaths = [ ReadWritePaths = [
cfg.stateDir cfg.stateDir
cfg.cacheDir cfg.cacheDir
@ -296,6 +382,20 @@ in
}; };
}; };
systemd.services.borgbackup-job-rabbi-gerzi = {
after = [
"sops-install-secrets.service"
"network-online.target"
"postgresql.service"
"${setupService}.service"
];
wants = [
"network-online.target"
"postgresql.service"
"${setupService}.service"
];
};
services.nginx = { services.nginx = {
enable = lib.mkDefault true; enable = lib.mkDefault true;
recommendedGzipSettings = lib.mkDefault true; recommendedGzipSettings = lib.mkDefault true;