From 16e98c44b8da5ff484f5f91c9cfe3f43a7b66566 Mon Sep 17 00:00:00 2001 From: Greg Hellings Date: Mon, 13 Oct 2025 21:09:27 -0500 Subject: [PATCH] Change backups to Restic --- hosts/linode/nextcloud.nix | 1 - hosts/linode/postgres.nix | 1 - modules/nixos/backup.nix | 55 ++++++++++--------------------------- secrets/restic-pw.age | Bin 2161 -> 2114 bytes 4 files changed, 14 insertions(+), 43 deletions(-) diff --git a/hosts/linode/nextcloud.nix b/hosts/linode/nextcloud.nix index 743b123..a309538 100644 --- a/hosts/linode/nextcloud.nix +++ b/hosts/linode/nextcloud.nix @@ -33,6 +33,5 @@ greg.backup.jobs.nextcloud-bkup = { src = "/var/lib/nextcloud"; dest = "nextcloud-backup"; - id = "nextcloud-backup"; }; } diff --git a/hosts/linode/postgres.nix b/hosts/linode/postgres.nix index e7db156..3de9363 100644 --- a/hosts/linode/postgres.nix +++ b/hosts/linode/postgres.nix @@ -54,6 +54,5 @@ greg.backup.jobs.greg-postgresql-backup = { src = config.services.postgresqlBackup.location; dest = "linode-postgres"; - id = "linode-postgres"; }; } diff --git a/modules/nixos/backup.nix b/modules/nixos/backup.nix index fb1a47b..6f33806 100644 --- a/modules/nixos/backup.nix +++ b/modules/nixos/backup.nix @@ -1,33 +1,24 @@ { lib, config, - pkgs, ... }: let cfg = config.greg.backup; - where = j: "${config.services.syncthing.dataDir}/daily.0/${j.dest}"; - - postexec = pkgs.writeShellApplication { - name = "postexec"; - runtimeInputs = [ pkgs.coreutils ]; - text = '' - chown -R ${config.services.syncthing.user} ${config.services.syncthing.dataDir} - ''; - }; - makeSyncFolders = _: job: { - devices = [ "chronicles" ]; - enable = true; - id = job.id; - label = job.dest; - path = where job; - type = "sendonly"; + inherit (job) user; + initialize = true; + passwordFile = config.age.secrets.restic-pw.path; + paths = [ job.src ]; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + ]; + repository = "rest:nas1.shire-zebra.ts.net:30248/${job.dest}"; }; - - makeRsnapshot = _: job: "backup ${job.src}/ ${job.dest}/"; in with lib; { @@ -50,9 +41,10 @@ with lib; dest = mkOption { type = types.str; }; - id = mkOption { + user = mkOption { type = types.str; - description = "The unique folder ID for this"; + default = "root"; + description = "User to run backup as - defaults to root"; }; }; } @@ -67,27 +59,8 @@ with lib; restic-pw.file = ../../secrets/restic-pw.age; restic-env.file = ../../secrets/restic-env.age; }; - greg.syncthing = { - enable = true; - }; services = { - syncthing.settings.folders = mapAttrs makeSyncFolders cfg.jobs; - rsnapshot = { - enable = true; - enableManualRsnapshot = true; - extraConfig = - '' - snapshot_root ${config.services.syncthing.dataDir}/ - retain daily 7 - retain weekly 2 - cmd_postexec ${lib.getExe postexec} - '' - + (builtins.concatStringsSep "\n" (mapAttrsToList makeRsnapshot cfg.jobs)); - cronIntervals = { - daily = "19 02 * * *"; # At 2:19 am every day - weekly = "19 01 * * 1"; # At 1:19 am every Monday - }; - }; + restic.backups = mapAttrs makeSyncFolders cfg.jobs; }; }; } diff --git a/secrets/restic-pw.age b/secrets/restic-pw.age index e970c4ff6c3b4ecde0e5b7ad1f6da544f318e8c1..1b58c546805e3c4dca521752ad2202fc50b4bdb0 100644 GIT binary patch literal 2114 zcmZYAIjh8K9R~0|h}Z}!qUjXkG0RM5G9W_sWU}uIT4b^(lYN^+@B`QgR||{V*;;8K zRu}AUuQnEb1si)$eatP<%#n2Ep6j*@8_~>f7*>XyrRI{&%tRb-qHlaar6dW z&P!BnU>>TEl#r@BIr>f_9JHvOGGoRcwQgq{djl&8gDk3u*V9zdEILB7tHVWKNuD27uZyY5 z4DwP;y+kIUJrr(BGP^#wQP8|ViigV;&5f58ABiojh^LTfn{Xv zB?mJbt7jp;j=8PEo1!d~TZS>2xQ*kzpRZaK06rSUH~*AE1{0>jOxzKl%~X92^bW?J zFHEw}Lo7gR+ixGW;9i=K4b(D&9$hLwx%acib}rjAa>}XDdcr7LfF*6Yv&Xq2IS&Ek z2e~gbmMTP^6Geo&g+X^cmfWak6}J`POeM{D)EctNM=c64(kHx?u9tuc8y7pPru17&Xise7jP`l31kK z@t zx)R$?Ub|jU!l>VA>?0^J^nTGA+#o*QMjAzi=Ag8W)F$egQQfCzSqX=H%HEW{1hk1XIu2Mf*Ree_BGn?e{evcj{fm*4?%j9#RoR1nsY|+&K z%|AYvUFiU(qzho(G>R`dW7w=Z+jg-gu}p*4Or*nJ?tkna+k?^X{#ZnR+Do5 z88&FICknFOI$MLAZpuGugwuMs0agvRkAYCXCQ~V+S8Vs}!m=jPGtpzehgGT|bMI|_ zUgf~bM5{BJ9gc`W6cb3Om20_TvL}EIYF{iQcPzRLz@RYt4Lb7gzvBS znvBh6 z#_+D^SVlQ(-RTED!`sa~bH}D12Y)pV^@RW@zvGmbD+e#0ZJ=&0mt33c{IOimn;S+? zsx7^iN~#q8ya8?F_c?g!m1lKoDmS`0F>yNVlPfd*NNGOz5S?WtR2zjt{>r;C5Yfd+ zz8!XGdao3Y#qg7~1__N;9-WrxrlYU(zX_=87F= z^bxWv4XY`I_o&Jl%lpcp)~)~v?%T?&kaza+*yrGC`RNG~Swfp4Sk0nCxOW|ta?Imu zeALcqk2xf`D^p;TCOIVrW_!a+?dJK6!`pHcX3JE!;p)OLAD}dc016aI^Z0tg-Y9S9 ztbxLfzq)e7F~Zq>9&vtC76@bDDP)1Sw>J=PgX2o4lDvaF$% znFgX6u4^R%r{5NT{vPnBzy0!yU;p5rf9U`C_1}O0yMKKBts4CCS6}{Q`)2nS<2%3j l&5wTc*YE!88$bNdS2g(G=zl-^{ujSuzm39Q;vxU<{{sOetlt0t literal 2161 zcmZXVJIL&K8OCJ`m1!*3N=I;!C45dUlT1by54qnblSw8w1UL6gGP&Q=*`7vmD+@Uw z+HJ9dV6$u^sNk^_)Xq*URuBY11gHMK`d|Fs=Xsy^`Flz96qP}{)cvh0zg@M-ZiF^Z z-`#dy`V@sQibBUNwjaD~+BUA;$eFe%w%f7+dafgJ2Oo-n30jC%^oU`^z7`;myeJ!- zx-2IpL`o!GYd~oGXcl>hrW{8zk1cF!?JTOgMdUp3oK`JNVNBaKLCTvCw0z#T*hsk+ z;@wWMJP|48-sKSB!3hWlBc{@66B?cx-|T^w6O~U~eKun`Th|onG#TR39OrJHgy7&& z3ZBynwK&JgRupsuDU4&2ckLhrz$xpvPPmgPEX?P8;zDUr9fOk1nb-hI&kS8)#7K`X zWg;v48&ie|e2eFc#MbrDA*Iia-tm|}r#a&7;!j($y-=!22LX2USuk-*AB3{0o74Ru z*Db@-AyOf>WbhEUY0P^)R~78cWrTqI_1UQ=2Kr*#5Um4;11IOE$QVx?Gvsspm7du=iDd<^Kg|Yg0Juy zJF?6MyS8==tvyQ%UemgPAfIGCp0CPqva{0a{en8T3ZS5-@LU_Ar7@Ij?}H)roo=FQ zk@mG(XvhG2*$I!pU`iy=XD?B^n{nWvgBvulNPgrlop#&q3@ zygVZlD8ilRG!mb@gSI6`Zy6~H4nvAg&KMjgG-^pBs70o4Q`crjFC>9x?4Eq2L=9<% zReKoo?j|msYBh^|#EebI93n`BTaAy&JKe`!@|=cWOAFPuN{G*P_Em|? zsSEkmDllL#DYbsMQ*Zf>Ms zQ$L41dI=ai*#t{?-p#QTyRLVn6TXI~dEwxfEF`wHPT-V5( zvhfb}h+~oFz#4yz?1OHf0Fp)|ERk99y33O;xaTd4q7T=fwK7|;W2|i_Tix47+PW}d zU)l#lAThn?Vb09m9d{S9kx=gIO=8({+Q3BM?y)nQ%@U6`EtFUUJL98cu16ca^T^c) zM>xhjxp|>256|POZO=v_=}YA^-VE*T8UYIS-3r65w3CxrIas^*T!S8Cm#a3+JiDlY zYL*Mnz+sTE;CQF0X(F=Lgs=;cl(nWGx@lFx=h~{WuVvNupi=3_dWh z-DLq}N^X0p{O+duwVhns9mfmRb8Y*mhOfj{4ndtnHLoq|&H}f12{bi)c9DFSfW%w(}V_^E38tkyF60z^t3e{l*a(f zixHj=Lg~=RQD>i!J`GXP3?B;Ex(S`Ls0YsG(~r%!{Te=fqy(?t|JPT4-oO3fPrqdR z>YJ}VGr#}lC%^gN_wW7k8$WvYZ-RD34