From 8d8bdc1ab779e9155cc1f52dcf8ea0b8226a468b Mon Sep 17 00:00:00 2001 From: wo2wz <189177184+wo2wz@users.noreply.github.com> Date: Tue, 30 Sep 2025 22:14:37 -0400 Subject: [PATCH] drone: add restic local backups --- modules/nixos/homeserver/default.nix | 1 + modules/nixos/homeserver/restic.nix | 75 ++++++++++++++++++++++++++++ modules/nixos/homeserver/sops.nix | 3 ++ secrets/secrets.yaml | 8 ++- 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 modules/nixos/homeserver/restic.nix diff --git a/modules/nixos/homeserver/default.nix b/modules/nixos/homeserver/default.nix index 4cc61af..82a0b09 100755 --- a/modules/nixos/homeserver/default.nix +++ b/modules/nixos/homeserver/default.nix @@ -6,6 +6,7 @@ ./caddy.nix ./cloudflared.nix ./nextcloud.nix + ./restic.nix ./sops.nix ./uptime-kuma.nix ./vaultwarden.nix diff --git a/modules/nixos/homeserver/restic.nix b/modules/nixos/homeserver/restic.nix new file mode 100644 index 0000000..81e18ff --- /dev/null +++ b/modules/nixos/homeserver/restic.nix @@ -0,0 +1,75 @@ +{ config, pkgs, ... }: + +{ + # for use as rclone backend + environment.systemPackages = [ pkgs.rclone ]; + + systemd.services.db-dump = { + wantedBy = [ "restic-backups-main.service" "restic-backups-offsite.service" ]; + script = '' + if [ ! -d /var/backups/db-backup ]; then + mkdir -p -m 600 /var/backups/db-backup + fi + + ${pkgs.sqlite}/bin/sqlite3 /var/lib/vaultwarden/db.sqlite3 ".backup /var/backups/db-backup/vaultwarden.sqlite3" + ${pkgs.sqlite}/bin/sqlite3 /var/lib/uptime-kuma/kuma.db ".backup /var/backups/db-backup/kuma.db" + + ${pkgs.sudo}/bin/sudo -u authentik -- ${pkgs.postgresql}/bin/pg_dump > /var/backups/db-backup/dump-authentik + ${pkgs.sudo}/bin/sudo -u onlyoffice -- ${pkgs.postgresql}/bin/pg_dump > /var/backups/db-backup/dump-onlyoffice + ${pkgs.sudo}/bin/sudo -u zipline -- ${pkgs.postgresql}/bin/pg_dump > /var/backups/db-backup/dump-zipline + ${pkgs.sudo}/bin/sudo -u postgres -- ${pkgs.postgresql}/bin/pg_dumpall -g > /var/backups/db-backup/dump-globals + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + }; + + services.restic.backups = { + main = { + initialize = true; + repository = "/mnt/external/backup/restic"; + passwordFile = config.sops.secrets."restic/password".path; + timerConfig = { + OnCalendar = "03:00"; + Persistent = true; + }; + + paths = [ + "/var/lib/private/authentik" + "/var/lib/private/uptime-kuma" + "/var/lib/nextcloud" + "/var/lib/vaultwarden" + "/var/backups/db-backup" + ]; + # exclude databases since they are covered separately + exclude = [ + "*.db" + "*.db-shm" + "*.db-wal" + "*.sqlite3" + "*.sqlite3-shm" + "*.sqlite3-wal" + ]; + + backupCleanupCommand = "rm -r /var/backups/db-backup/*"; + }; + +# offsite = { +# initialize = true; +# repository = "rclone:protondrive:restic"; +# passwordFile = config.sops.secrets."restic/password".path; +# timerConfig = { +# OnCalendar = "3:05"; +# Persistent = true; +# }; +# rcloneOptions = { protondrive-replace-existing-draft = true; }; +# rcloneConfigFile = config.sops.secrets."restic/rclone/offsite".path; + +# paths = config.services.restic.backups.main.paths; +# exclude = config.services.restic.backups.main.exclude; + +# backupCleanupCommand = "rm -r /var/backups/db-backup/*"; +# }; + }; +} diff --git a/modules/nixos/homeserver/sops.nix b/modules/nixos/homeserver/sops.nix index 2716144..eab1590 100755 --- a/modules/nixos/homeserver/sops.nix +++ b/modules/nixos/homeserver/sops.nix @@ -33,6 +33,9 @@ group = "onlyoffice"; }; + "restic/password" = {}; + "restic/rclone/offsite" = {}; + "vaultwarden/secrets.env".restartUnits = [ "vaultwarden.service" ]; "zipline/secrets.env".restartUnits = [ "zipline.service" ]; diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml index 524d1d5..84b40ba 100755 --- a/secrets/secrets.yaml +++ b/secrets/secrets.yaml @@ -9,6 +9,10 @@ nextcloud: adminpass: ENC[AES256_GCM,data:eSQQkhcXB4s9pnJ1hToGgyEr+rGlMIKHLsU0EemMOng=,iv:USq1winT7GPGVKwDjfF+cFs/dj395zgXyTVQ/x1KNS0=,tag:Me6MKsZwUc4sjZIPfZmk+A==,type:str] onlyoffice: jwt: ENC[AES256_GCM,data:NVDBwIY6wBFUkm4ry97cbO2uSczzN5IDR17sroVn5hXcMRNNxWitp3hU7qruj4wUEg9BGrCyFgknm6tBss0DAaCnbGAynCdaaaIhYjFLTUx4tHzVXZflWaEM+c0nYaTf2to4B3c2r+DpRRBjlfQbJXjlaW2kpZ07EmWo11a5Tn8=,iv:ZO4TpnVppBHhw5e72x+PqUY5QT6M96s/vZDIDDcnLBE=,tag:PA7WCqwaV9fAeJG+1wiXfg==,type:str] +restic: + password: ENC[AES256_GCM,data:sWFhBWXpYktef9Ajf5eDlOljcMmJur1PkKSalrmt9yXPYto117YMeI7zyXDZqlk9bDoqj28d8/pl2lP0itBpOZc+GoPZfDns+RyJUrP0S/0pV5gXA72/9g4Yqg9eSuXdeAbFYb9CnuHUi8+HJnIULPKOaqpwpwKaRsDAN5KVsAA=,iv:RCXcp0/cpT6WHM6v4zZtwD+w1epYp/JXvSWON8/Txyk=,tag:ffdQYuuIfuJQJGIXi1HaMw==,type:str] + rclone: + offsite: ENC[AES256_GCM,data:Mo37uC7lttsQmmnDsK+Zf54e4gb6+dAYwaPgvmEJ1IqCjj/mbpgbClwHvYrg+dKAoVxiM9Vacs3m2KfuWMV5IIGp+SQ3BSXHsy/Uh1yuCELChyrws8jtAq8ySY2VLniK44baIUhMT3/5i3JockfiJ2YWs188/0DWyPSFm4qWrK6BwLeq4PMcvNNKtawHlgavG+WaXw3aVskzYeBaDa00,iv:YszzzTN3ig+S28l6TIiruUg/EL0NFTmeihnlC+PjFH0=,tag:KxNiP5rbp9C4l3NJORktXg==,type:str] tailscale: drone.taild5f7e6.ts.net.crt: ENC[AES256_GCM,data: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,iv:let5DG6B4Dy1UWmldZPQ5dfUTU4q3Rc+WXdUXgjI8Wk=,tag:vIlcLk2mbCY5lwmI0iC00w==,type:str] drone.taild5f7e6.ts.net.key: ENC[AES256_GCM,data:PYx24EEH4evfSC+TxJ8myVs6A4nMMCVPD4IhA5DmwHbB13li7O8q/+45MpdXimEXN3abvucgSQnPDnpQ2OZyLK7ym03abrlFZneQXe3IcuDX2EHMIRq5nFN6VESt3yB2PFOb1aEXYeCBj8bkeebi9zirg7BJz3jRChYsP+BBsMCXtMN+w5VtFDhsh87rBmXo4O9zO95S8NkG9R9+f/fBN7AF5K4hR0eldJe+86QP7fKjDYDiATucuU0Up3uqx6vMcFfiH9UnhMy287Hm6NJQ3oKbVUeT4Vz7/lHCamkWU7083ig=,iv:b83/uKx0j5gwLdGIwpQtAEsx9FZ2y4kATD78iJyWYlY=,tag:5QCcCweEk8bX6CDW77AYlQ==,type:str] @@ -27,7 +31,7 @@ sops: N0U5bkt4aXJOS3N0Z2N4YTg4TDVUVncKCQLUTMmdM/IPzV3NDRhPdta1tvXxy/6P RYbLzlUryw+tqfTp8nDrdxyOWScLNzPOswAq0Qf7VMcEQ5bJEkAOhQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-09-05T22:50:20Z" - mac: ENC[AES256_GCM,data:rIjAHKbQS0/aFAWHYYI/65JnJONorb5h6WFjEu9BlOIkxsJQqIvRiol/qciXc9W+PoV0d2iSDmB4dOJIbuAeZogELU2/dPBTwWUbIFlSxsK0FfmncInKshWFW92lCVC11K9DID9aS0SoH8WW/pybdYTI98mazjvkWDHhJ3u7JG0=,iv:E4ZMp+jD76EUNPBUkE/EcfIu1llLMc2wOYBXbMtHNEI=,tag:i0To+y4yBBTqkvKZjfiOAA==,type:str] + lastmodified: "2025-09-30T03:24:04Z" + mac: ENC[AES256_GCM,data:sBnTE8I4hWkz56Lt0pUUtuGDduYikrhZqIK1egiMmq/QruSM0lpenJkPifJwRVXul6lL04VayCvkGxFIvWW9nKvhOHBiWO9C9kicj+maOzBv/MF5G+UhdRW50O/m/ZfPU0QPmAmo3e2iuwdgNqQIk3a4FPLP5crGMFuYtZKTDUg=,iv:cdqBKo11Ph//oXbupTL764y+8I1mESExhWvjjjT2pVs=,tag:KaEhk6iVvbdiG8UGKjqffg==,type:str] unencrypted_suffix: _unencrypted version: 3.10.2