diff --git a/hosts/stratus/containers/nextcloud/backup.nix b/hosts/stratus/containers/nextcloud/backup.nix new file mode 100644 index 0000000..6fc18c8 --- /dev/null +++ b/hosts/stratus/containers/nextcloud/backup.nix @@ -0,0 +1,65 @@ +{ + config, + pkgs, + lib, + dataDir, + ... +}: +{ + sops.secrets = { + "restic/environment" = { + owner = config.users.users.nextcloud.name; + inherit (config.users.users.nextcloud) group; + }; + "restic/password" = { + owner = config.users.users.nextcloud.name; + inherit (config.users.users.nextcloud) group; + }; + }; + + systemd.tmpfiles.rules = [ + "d ${dataDir}/backup 700 nextcloud nextcloud -" + "d /var/cache/restic-backups-nextcloud 700 nextcloud nextcloud -" + ]; + + services.restic.backups.nextcloud = { + initialize = true; + user = config.users.users.nextcloud.name; + + repository = "s3:https://s3.eu-central-003.backblazeb2.com/stork-atlas/nextcloud"; + environmentFile = config.sops.secrets."restic/environment".path; + passwordFile = config.sops.secrets."restic/password".path; + + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 6" + "--keep-yearly 1" + ]; + + backupPrepareCommand = '' + ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --on + ${lib.getExe' config.services.postgresql.package "pg_dump"} nextcloud --format=custom --file=${dataDir}/backup/db.dump + ''; + backupCleanupCommand = '' + ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --off + ''; + paths = [ + "${dataDir}/home/data" + "${dataDir}/home/config/config.php" + "${dataDir}/backup" + ]; + }; + + environment.systemPackages = [ + (pkgs.writeShellApplication { + name = "nextcloud-restore"; + text = '' + sudo -u nextcloud ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --on + sudo -u nextcloud restic-nextcloud restore --target / latest + sudo -u nextcloud pg_restore --clean --if-exists --dbname nextcloud ${dataDir}/backup/db.dump + sudo -u nextcloud ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --off + ''; + }) + ]; +} diff --git a/hosts/stratus/containers/nextcloud/default.nix b/hosts/stratus/containers/nextcloud/default.nix index 4e3d9d2..5038684 100644 --- a/hosts/stratus/containers/nextcloud/default.nix +++ b/hosts/stratus/containers/nextcloud/default.nix @@ -7,7 +7,10 @@ ... }: { - imports = [ ./email-server.nix ]; + imports = [ + ./email-server.nix + ./backup.nix + ]; sops.secrets."nextcloud/admin-password" = { owner = config.users.users.nextcloud.name; diff --git a/hosts/stratus/containers/nextcloud/secrets.yaml b/hosts/stratus/containers/nextcloud/secrets.yaml index 77c7a31..272a59c 100644 --- a/hosts/stratus/containers/nextcloud/secrets.yaml +++ b/hosts/stratus/containers/nextcloud/secrets.yaml @@ -2,6 +2,9 @@ tailscale-auth-key: ENC[AES256_GCM,data:KshGpoyKTQQgshWFSwhGWPtwPfP3S2fLkJBxqfu1 nextcloud: admin-password: ENC[AES256_GCM,data:RaFNoEJj2flmwIu2Q/5UgRbITve7CzFg8udQclJO,iv:d95Vo9HMRzmoSU3gcQqO5uP7yW6n7PF6Nx3s6A9bgmc=,tag:ruIW8Ov+wQPOPBWV61MnWw==,type:str] gmail-password: ENC[AES256_GCM,data:RJXg4KYYwjg2CyzQM9wovDSqB8M=,iv:Tf8egrzoG3rRbzufJGHCTr6W+nCEnJJaSe6hpvr1AmM=,tag:GjlgIEqQDUtjn3mm1QT1uw==,type:str] +restic: + environment: ENC[AES256_GCM,data:bYC7JBKvOMUdqB3X/Z9Nh4g8mhSJpqo63vU3zIrdSO+zlRF+PT+n4yofZe8D47Wz46YGAfwnKXGvAy2WQwHsDcMfdWW85e/1ttV5eESWMotSBM7WzpyFRjNDg+vCy4nWkWI=,iv:RVBMlsOwJCehMuJ2Hzls+gnzUIJM8MjdLu5uMJczugw=,tag:hds43pJX/hpBLwXTujiJ8w==,type:str] + password: ENC[AES256_GCM,data:yMs1EG39X1+RYcgeM3SFi38ypOU=,iv:vsEl9jLR3DcqRxJmH5cpIe1+I2W49Hj12oOfwrymznI=,tag:uevinZPEfj0J4KFkTLsV5g==,type:str] sops: kms: [] gcp_kms: [] @@ -26,8 +29,8 @@ sops: aWFqYXYrMmJBbEQwQWxza1lrdmU4bmMKm0QbJP1QiNVOA7slpocaPxkq9orE8jrP xxrDtRUZhvEOEZuCD61wWTfgdeI7SFWaSJkN6MgPlvRyuYQ+3TZh3Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-09-02T11:38:31Z" - mac: ENC[AES256_GCM,data:E2L8j21dhHLQ/OCIZNMqlH1C5XX0uSGmuQIjetiE8s/LX4fZSR9s4sPzub3gLI5h3EVJKzMU2UFXZATMUfe/1t4PP5nIuggUtxD+VWxtHNaVHJMs+wEWKYE+nITyZ7HGvwBr0sMQ3Sb2DuiQ729nr9hLn1Mbn7uc5o+Z2RJg5Cc=,iv:jEaBwYsO3hW5NtmmZrL6H23qDcTSAGuBLjPRi60Lzco=,tag:pGpL80onRUVQfIYChaBxSg==,type:str] + lastmodified: "2024-09-02T22:12:46Z" + mac: ENC[AES256_GCM,data:lM947a3lS+ultYxIIrmyUe9rGtho1MPQ31cVWeP9JitkwMgP8kZFWV/HYMWIP6hUvvAwrdyMnSsyxRwDAY5EcEPnoGcnCtgctlAjsGb/B9HECCfD/ZeEiGAXGEfsojgkUJIEx/XeoD/FstyNB7CfsYoEHnB06YUFJzk1hj6+JME=,iv:P5wB86h3gUEnveLSMqRjH94gHfdPL2IBCRX3S8UTMBg=,tag:F7ZqYCEuPE0Je01KhAFYIA==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.0 diff --git a/hosts/stratus/containers/paperless/backup.nix b/hosts/stratus/containers/paperless/backup.nix index 52c2791..f2c631b 100644 --- a/hosts/stratus/containers/paperless/backup.nix +++ b/hosts/stratus/containers/paperless/backup.nix @@ -23,8 +23,8 @@ ]; services.restic.backups.paperless = { - inherit (config.services.paperless) user; initialize = true; + inherit (config.services.paperless) user; repository = "s3:https://s3.eu-central-003.backblazeb2.com/stork-atlas/paperless"; environmentFile = config.sops.secrets."restic/environment".path; @@ -48,14 +48,13 @@ ] } ''; - paths = [ "${dataDir}/backup" ]; }; users.users.paperless.extraGroups = [ "redis-paperless" ]; environment.systemPackages = [ (pkgs.writeShellApplication { - name = "restore-paperless"; + name = "paperless-restore"; text = '' sudo -u paperless restic-paperless restore --target / latest sudo -u paperless ${dataDir}/paperless-manage document_importer ${dataDir}/backup