From b5defe1bf08cd8666f670101d2e01d64ead6552f Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Mon, 12 Jan 2026 00:48:54 +0000 Subject: [PATCH] Add restic backup for all corp services --- flake.lock | 106 ++++++++++++++++---------------- modules/system/authentik.nix | 34 ++++++++++ modules/system/cloudreve.nix | 35 ++++++++++- modules/system/label-studio.nix | 32 ++++++++++ modules/system/librechat.nix | 53 ++++++++++++++++ modules/system/synapse.nix | 33 ++++++++++ modules/system/twenty-crm.nix | 34 +++++++++- modules/system/vikunja.nix | 32 ++++++++++ 8 files changed, 304 insertions(+), 55 deletions(-) diff --git a/flake.lock b/flake.lock index 0171a5e..aeca905 100644 --- a/flake.lock +++ b/flake.lock @@ -14,11 +14,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1757062396, - "narHash": "sha256-403iuoMVVjk64sF1GgZfrRwOnVU1H14sflE+LNp927c=", + "lastModified": 1763643080, + "narHash": "sha256-jlYmjrTw3g5iOYDZBGb5Plw6IyRa+WY60e3GzU19bkk=", "owner": "nix-community", "repo": "authentik-nix", - "rev": "22827e9a0cc002a076ee8bd14c3433ebc6c87f95", + "rev": "4a670757083d94a9dceb4929eb88eb9995bc1363", "type": "github" }, "original": { @@ -30,16 +30,16 @@ "authentik-src": { "flake": false, "locked": { - "lastModified": 1755873658, - "narHash": "sha256-5l1g55b0xozGg0NaZFimiO5JbHGcudaNSEn1/XsweaU=", + "lastModified": 1763564826, + "narHash": "sha256-xBnAfoAOUslOrxNzY5kV0h67qWMXKZnPC/wgRGXZleQ=", "owner": "goauthentik", "repo": "authentik", - "rev": "dd7c6b29d950664deadbcf5390272619a8bf9a5e", + "rev": "2fedc3d0a0ba91c16bb71bd4b2432108ca02e890", "type": "github" }, "original": { "owner": "goauthentik", - "ref": "version/2025.8.1", + "ref": "version/2025.10.2", "repo": "authentik", "type": "github" } @@ -51,11 +51,11 @@ ] }, "locked": { - "lastModified": 1757255839, - "narHash": "sha256-XH33B1X888Xc/xEXhF1RPq/kzKElM0D5C9N6YdvOvIc=", + "lastModified": 1765794845, + "narHash": "sha256-YD5QWlGnusNbZCqR3pxG8tRxx9yUXayLZfAJRWspq2s=", "owner": "nix-community", "repo": "disko", - "rev": "c8a0e78d86b12ea67be6ed0f7cae7f9bfabae75a", + "rev": "7194cfe5b7a3660726b0fe7296070eaef601cae9", "type": "github" }, "original": { @@ -87,11 +87,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "type": "github" }, "original": { @@ -105,11 +105,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1754487366, - "narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=", + "lastModified": 1762980239, + "narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18", + "rev": "52a2caecc898d0b46b2b905f058ccc5081f842da", "type": "github" }, "original": { @@ -126,11 +126,11 @@ ] }, "locked": { - "lastModified": 1749398372, - "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=", + "lastModified": 1765495779, + "narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569", + "rev": "5635c32d666a59ec9a55cab87e898889869f7b71", "type": "github" }, "original": { @@ -249,16 +249,16 @@ ] }, "locked": { - "lastModified": 1748294338, - "narHash": "sha256-FVO01jdmUNArzBS7NmaktLdGA5qA3lUMJ4B7a05Iynw=", + "lastModified": 1754860581, + "narHash": "sha256-EM0IE63OHxXCOpDHXaTyHIOk2cNvMCGPqLt/IdtVxgk=", "owner": "NuschtOS", "repo": "ixx", - "rev": "cc5f390f7caf265461d4aab37e98d2292ebbdb85", + "rev": "babfe85a876162c4acc9ab6fb4483df88fa1f281", "type": "github" }, "original": { "owner": "NuschtOS", - "ref": "v0.0.8", + "ref": "v0.1.1", "repo": "ixx", "type": "github" } @@ -326,11 +326,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1756386758, - "narHash": "sha256-1wxxznpW2CKvI9VdniaUnTT2Os6rdRJcRUf65ZK9OtE=", + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dfb2f12e899db4876308eba6d93455ab7da304cd", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", "type": "github" }, "original": { @@ -342,11 +342,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1753579242, - "narHash": "sha256-zvaMGVn14/Zz8hnp4VWT9xVnhc8vuL3TStRqwk22biA=", + "lastModified": 1761765539, + "narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "0f36c44e01a6129be94e3ade315a5883f0228a6e", + "rev": "719359f4562934ae99f5443f20aa06c2ffff91fc", "type": "github" }, "original": { @@ -389,11 +389,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1767051569, - "narHash": "sha256-0MnuWoN+n1UYaGBIpqpPs9I9ZHW4kynits4mrnh1Pk4=", + "lastModified": 1765687488, + "narHash": "sha256-7YAJ6xgBAQ/Nr+7MI13Tui1ULflgAdKh63m1tfYV7+M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "40ee5e1944bebdd128f9fbada44faefddfde29bd", + "rev": "d02bcc33948ca19b0aaa0213fe987ceec1f4ebe1", "type": "github" }, "original": { @@ -405,11 +405,11 @@ }, "nixpkgs_5": { "locked": { - "lastModified": 1744868846, - "narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=", + "lastModified": 1765457389, + "narHash": "sha256-ddhDtNYvleZeYF7g7TRFSmuQuZh7HCgqstg5YBGwo5s=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c", + "rev": "f997fa0f94fb1ce55bccb97f60d41412ae8fde4c", "type": "github" }, "original": { @@ -443,11 +443,11 @@ "systems": "systems_5" }, "locked": { - "lastModified": 1767448045, - "narHash": "sha256-g+LGq2LxOeCgf1M/xbk7gGqpZD3P66Isx2Z13W48npI=", + "lastModified": 1765643213, + "narHash": "sha256-1JU2vcsRXwjrQoDpNc8+E13vLEu8MwLaVfBQ3ktWFUw=", "owner": "nix-community", "repo": "nixvim", - "rev": "ce3ce82c09a5d9e552d0ef39ab15b417c2d893cb", + "rev": "0e8b4ccf0a4e4e90f9ca39295e807628a6e575e6", "type": "github" }, "original": { @@ -467,11 +467,11 @@ ] }, "locked": { - "lastModified": 1749730855, - "narHash": "sha256-L3x2nSlFkXkM6tQPLJP3oCBMIsRifhIDPMQQdHO5xWo=", + "lastModified": 1761730856, + "narHash": "sha256-t1i5p/vSWwueZSC0Z2BImxx3BjoUDNKyC2mk24krcMY=", "owner": "NuschtOS", "repo": "search", - "rev": "8dfe5879dd009ff4742b668d9c699bc4b9761742", + "rev": "e29de6db0cb3182e9aee75a3b1fd1919d995d85b", "type": "github" }, "original": { @@ -496,11 +496,11 @@ ] }, "locked": { - "lastModified": 1756087852, - "narHash": "sha256-4jc3JDQt75fYXFrglgqyzF6C6zLU0QGLymzian4aP+U=", + "lastModified": 1761781027, + "narHash": "sha256-YDvxPAm2WnxrznRqWwHLjryBGG5Ey1ATEJXrON+TWt8=", "owner": "pyproject-nix", "repo": "build-system-pkgs", - "rev": "6edb3ae27395cd88be3d64b732d1539957dad59c", + "rev": "795a980d25301e5133eca37adae37283ec3c8e66", "type": "github" }, "original": { @@ -517,11 +517,11 @@ ] }, "locked": { - "lastModified": 1756395552, - "narHash": "sha256-5aJM14MpoLk2cdZAetu60OkLQrtFLWTICAyn1EP7ZpM=", + "lastModified": 1763435975, + "narHash": "sha256-SKdpcVuJKMNEXloIpLXY+jDI42+6Ew21vdkl894DxHo=", "owner": "pyproject-nix", "repo": "pyproject.nix", - "rev": "030dffc235dcf240d918c651c78dc5f158067b51", + "rev": "7d3d8848358ccbd415afe2139f12b9e1508d3ace", "type": "github" }, "original": { @@ -570,11 +570,11 @@ "nixpkgs": "nixpkgs_5" }, "locked": { - "lastModified": 1752544651, - "narHash": "sha256-GllP7cmQu7zLZTs9z0J2gIL42IZHa9CBEXwBY9szT0U=", + "lastModified": 1765836173, + "narHash": "sha256-hWRYfdH2ONI7HXbqZqW8Q1y9IRbnXWvtvt/ONZovSNY=", "owner": "Mic92", "repo": "sops-nix", - "rev": "2c8def626f54708a9c38a5861866660395bb3461", + "rev": "443a7f2e7e118c4fc63b7fae05ab3080dd0e5c63", "type": "github" }, "original": { @@ -690,11 +690,11 @@ ] }, "locked": { - "lastModified": 1756466761, - "narHash": "sha256-ALXRHIMXQ4qVNfCbcWykC23MjMwUoHn9BreoBfqmq0Y=", + "lastModified": 1763421857, + "narHash": "sha256-8JurcmEzAkrpm+eUDm8W/+KkU/w/viAeyJhJlIX2qOQ=", "owner": "pyproject-nix", "repo": "uv2nix", - "rev": "0529e6d8227517205afcd1b37eee3088db745730", + "rev": "c9752c6c5915eece99505612d8f7805185cff990", "type": "github" }, "original": { diff --git a/modules/system/authentik.nix b/modules/system/authentik.nix index 87fa92c..ec73a85 100644 --- a/modules/system/authentik.nix +++ b/modules/system/authentik.nix @@ -45,6 +45,40 @@ with lib; name = "authentik"; }]; }; + services.restic.backups."authentik-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump authentik" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/authentik"; + }; + services.restic.backups."authentik-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/opt/authentik/certs" + "/opt/authentik/media" + "/opt/authentik/templates" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/authentik"; + }; sops.secrets.authentik-env = with config.virtualisation.oci-containers; { format = "dotenv"; group = "authentik"; diff --git a/modules/system/cloudreve.nix b/modules/system/cloudreve.nix index 40f563c..b50ee92 100644 --- a/modules/system/cloudreve.nix +++ b/modules/system/cloudreve.nix @@ -34,6 +34,39 @@ with lib; #listen_addresses = lib.mkForce "10.88.0.1,localhost"; #}; }; + services.restic.backups."cloudreve-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump cloudreve" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/cloudreve"; + }; + services.restic.backups."cloudreve-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/mnt/bigdisk/cloudreve" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/cloudreve"; + + }; sops.secrets.cloudreve-env = with config.virtualisation.oci-containers; { format = "dotenv"; group = "cloudreve"; @@ -43,7 +76,7 @@ with lib; sopsFile = ../../secrets/cloudreve.env; }; systemd.tmpfiles.rules = [ - "d /opt/cloudreve 0755 cloudreve cloudreve" + "d /mnt/bigdisk/cloudreve 0755 cloudreve cloudreve" ]; # The container here comes from a private repository. In order to get it you need to buy a pro license # and download and configure the image via https://cloudreve.org/manage diff --git a/modules/system/label-studio.nix b/modules/system/label-studio.nix index 88c7fe7..3a1da5d 100644 --- a/modules/system/label-studio.nix +++ b/modules/system/label-studio.nix @@ -15,6 +15,38 @@ with lib; name = "label-studio"; }]; }; + services.restic.backups."label-studio-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump label-studio" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/label-studio"; + }; + services.restic.backups."label-studio-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/mnt/bigdisk/label-studio" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/label-studio"; + }; sops.secrets.label-studio-env = { format = "dotenv"; group = "label-studio"; diff --git a/modules/system/librechat.nix b/modules/system/librechat.nix index 9149568..18cc19a 100644 --- a/modules/system/librechat.nix +++ b/modules/system/librechat.nix @@ -37,6 +37,59 @@ in search_path = "\"$user\", public, vector"; }; }; + services.restic.backups."mongodb" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u mongodb" + "${pkgs.mongodb}/bin/mongodump --archive=/mnt/bigdisk/temp/mongodb" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/mongodb"; + }; + services.restic.backups."rag_api-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump rag_api" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/rag_api"; + }; + services.restic.backups."librechat-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/opt/librechat" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/librechat"; + + }; sops.secrets.librechat-env = { format = "dotenv"; group = "librechat"; diff --git a/modules/system/synapse.nix b/modules/system/synapse.nix index e63747b..53fa65b 100644 --- a/modules/system/synapse.nix +++ b/modules/system/synapse.nix @@ -74,6 +74,39 @@ in { # name = "matrix-synapse"; # }]; #}; + services.restic.backups."synapse-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump matrix-synapse" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/matrix-synapse"; + }; + services.restic.backups."synapse-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/var/lib/matrix-synapse" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/authentik"; + + }; sops.secrets."matrix-synapse.yaml" = { format = "yaml"; group = "matrix-synapse"; diff --git a/modules/system/twenty-crm.nix b/modules/system/twenty-crm.nix index 453983c..5198d23 100644 --- a/modules/system/twenty-crm.nix +++ b/modules/system/twenty-crm.nix @@ -27,6 +27,38 @@ in { requirePass = "letmein"; user = user; }; + services.restic.backups."twenty-crm-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump ${user}" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/twenty-crm"; + }; + services.restic.backups."twenty-crm-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/mnt/bigdisk/twenty-crm-data" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/authentik"; + }; sops.secrets.twenty-crm-env = { format = "dotenv"; group = user; @@ -52,7 +84,7 @@ in { ports = [ "127.0.0.1:${port}:3000" ]; volumes = [ "/run/postgresql/.s.PGSQL.5432:/run/postgresql/.s.PGSQL.5432" - "twenty-crm-data:/app/packages/twenty-server/.local-storage" + "/mnt/bigdisk/twenty-crm-data:/app/packages/twenty-server/.local-storage" "/home/eliribble/src/twentycrm/entrypoint.sh:/app/entrypoint.sh" ]; }; diff --git a/modules/system/vikunja.nix b/modules/system/vikunja.nix index 674cb0d..3f8de40 100644 --- a/modules/system/vikunja.nix +++ b/modules/system/vikunja.nix @@ -15,6 +15,38 @@ with lib; name = "vikunja"; }]; }; + services.restic.backups."vikunja-db" = { + # We can use this due to overridding restic with unstable + command = [ + "${lib.getExe pkgs.sudo}" + "-u postgres" + "${pkgs.postgresql}/bin/pg_dump vikunja" + ]; + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag database" + ]; + passwordFile = "/var/run/secrets/restic-password"; + pruneOpts = [ + "--keep-daily 14" + "--keep-weekly 4" + "--keep-monthly 2" + "--group-by tags" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/vikunja"; + }; + services.restic.backups."vikunja-files" = { + environmentFile = "/var/run/secrets/restic-env"; + extraBackupArgs = [ + "--tag files" + ]; + initialize = true; + passwordFile = "/var/run/secrets/restic-password"; + paths = [ + "/var/lib/vikunja" + ]; + repository = "s3:s3.us-west-004.backblazeb2.com/gleipnir-backup-corp/vikunja"; + }; services.vikunja = { enable = true; frontendHostname = "todo.gleipnir.technology";