diff --git a/hosts/nixos/noximilien/configuration.nix b/hosts/nixos/noximilien/configuration.nix index 2ce48d5..a998fba 100644 --- a/hosts/nixos/noximilien/configuration.nix +++ b/hosts/nixos/noximilien/configuration.nix @@ -32,7 +32,8 @@ # ../../../profiles/services/tmate-server.nix # opens port 42244 # TODO: move outside of home net # TODO: - # ../../../profiles/backup + # ../../../profiles/backup/client + # ../../../profiles/backup/server.nix # setups the sftp user ../../../profiles/http # enables nginx+acme, defines mkDomain ../../../profiles/http/index diff --git a/profiles/backup/default.nix b/profiles/backup/client/default.nix similarity index 66% rename from profiles/backup/default.nix rename to profiles/backup/client/default.nix index 09b38f8..ae8d4f2 100644 --- a/profiles/backup/default.nix +++ b/profiles/backup/client/default.nix @@ -6,6 +6,32 @@ let sopsFile = lib.mkDefault ../../hosts/nixos/${hostName}/secrets.yaml; in +# 3-2-1 Backup Rule: +# * have 3 separate copies +# * on 2 different media +# * with 1 kept offsite + +# # borgbackup vs restic vs kopia vs diplicity +# https://mangohost.net/blog/duplicacy-vs-restic-vs-borg-which-backup-tool-is-right-in-2025/ +# https://onidel.com/restic-vs-borgbackup-vs-kopia-2025/ +# https://www.reddit.com/r/BorgBackup/comments/v3bwfg/why_should_i_switch_from_restic_to_borg/ +# https://www.aarsen.me/posts/2022-02-15-sweet-unattended-backups.html +# +# restic: +# * native s3, go, decent restore, good deduplication, simplicity, decent backup/restore speed, slow prunes on huge repos +# borgbackup: +# * clunky s3 (rclone), python/c, 1 machine per repo, backup goes brr, multiple encryption modes +# kopia: +# * native s3, go, fast restore, restore goes brr, flexible key management, no nixos module +# duplicity: +# * global deduplication, but global job, paid gui +# zrepl: +# * requires zfs on both ends + +# TODO: can i make restic backup from a zfs snapshot for atomicity? +# https://www.aarsen.me/posts/2022-02-15-sweet-unattended-backups.html#pulling-it-together +# https://gist.github.com/stackcoder/ccb3b17812ed11700ee83d762b970b98 + { options = { pbsds.backup.paths = lib.mkOption { @@ -15,7 +41,16 @@ in }; imports = lib.map notInVM [ - ./postgres.nix + # https://search.nixos.org/options?channel=unstable&query=backup + ./mysqlBackup.nix + ./postgresqlBackup.nix + # ./vaultwarden.nix # services.vaultwarden.backupDir + # ./gitea.nix # services.gitea.dump.enable + # ./forgejo.nix # services.forgejo.dump.enable + # stuff in /var/lib on nox: + # ./transmission.nix + # ./plex.nix + # ./thelounge.nix ]; config = notInVM { @@ -42,6 +77,8 @@ in # TODO: --skip-if-unchanged ? paths = [ "/var/lib" ] ++ config.pbsds.backup.paths; + + # TODO: How should the timer behave on a laptop? timerConfig.OnCalendar = "hourly"; pruneOpts = [ "--keep-daily 5" @@ -52,15 +89,15 @@ in in { "systems-meconium" = shared // { - # repository = "sftp:noximilien:/mnt/meconium/Backups/restic/system-${hostName}"; - repository = "sftp:noximilien:/mnt/meconium/Backups/restic/systems"; + # repository = "sftp:USER_TODO@noximilien:/mnt/meconium/Backups/restic/system-${hostName}"; + repository = "sftp:USER_TODO@noximilien:/mnt/meconium/Backups/restic/systems"; passwordFile = config.sops.secrets.restic_systems_password_meconium.path; # environmentFile = config.sops.secrets.restic_systems_environment_meconium.path; }; "systems-panorama" = shared // { - # repository = "sftp:eple:/mnt/panorama/Backups/restic/system-${hostName}"; - repository = "sftp:eple:/mnt/panorama/Backups/restic/systems"; + # repository = "sftp:USER_TODO@eple:/mnt/panorama/Backups/restic/system-${hostName}"; + repository = "sftp:USER_TODO@eple:/mnt/panorama/Backups/restic/systems"; passwordFile = config.sops.secrets.restic_systems_password_panorama.path; # environmentFile = config.sops.secrets.restic_systems_environment_panorama.path; }; diff --git a/profiles/backup/client/mysqlBackup.nix b/profiles/backup/client/mysqlBackup.nix new file mode 100644 index 0000000..6b42c8a --- /dev/null +++ b/profiles/backup/client/mysqlBackup.nix @@ -0,0 +1,24 @@ +{ lib, config, ... }: +let + mkIf = lib.mkIf config.services.mysql.enable; +in +{ + + pbsds.backup.paths = mkIf [ config.mysqlBackup.location ]; # "/var/backup/postgresql" + + services.mysqlBackup = mkIf { + enable = true; + databases = config.services.mysql.ensureDatabases; + # calendar = "*-*-* 01:15:00"; # nightly (default) + + # there is now way to select no compression... + # should be trivial to fix ;) + # https://github.com/NixOS/nixpkgs/blob/89c2b2330e733d6cdb5eae7b899326930c2c0648/nixos/modules/services/backup/mysql-backup.nix#L23-L45 + # https://github.com/NixOS/nixpkgs/pull/364630 + # compressionAlg = "gzip"; + # compressionAlg = "xz"; + # compressionAlg = "zstd"; + # compressionLevel = null; + }; + +} diff --git a/profiles/backup/postgres.nix b/profiles/backup/client/postgresqlBackup.nix similarity index 100% rename from profiles/backup/postgres.nix rename to profiles/backup/client/postgresqlBackup.nix diff --git a/profiles/backup/server.nix b/profiles/backup/server.nix new file mode 100644 index 0000000..da778f9 --- /dev/null +++ b/profiles/backup/server.nix @@ -0,0 +1,3 @@ + +# todo +# some "restrict,pty,command=..." ssh authorized_keys bullshit to verify restic, or maybe even just host the REST server?