This repository has no description
4.4 kB
118 lines
1{ config, pkgs, ... }:
2{
3 clan.core.vars.generators.borgbackup = {
4 files."borgbackup.ssh.id25519" = { };
5 files."borgbackup.ssh.id25519.pub".secret = false;
6 runtimeInputs = with pkgs; [
7 coreutils
8 openssh
9 ];
10 script = ''
11 ssh-keygen -t ed25519 -N "" -f $out/borgbackup.ssh.id25519
12 '';
13 };
14
15 # Ensure backup directory exists for pg_dump
16 systemd.tmpfiles.rules = [
17 "d /var/backup 0700 root root -"
18 "d /var/backup/postgresql 0700 root root -"
19 "d /var/backup/parley 0700 root root -"
20 ];
21
22 services.borgbackup.jobs.hetzner = {
23 paths = [
24 "/var/backup"
25 "/var/lib/bitwarden_rs"
26 "/var/lib/htgen-cyberlocker"
27 "/var/lib/htgen-paste"
28 "/var/lib/matrix-synapse/media_store/local_content"
29 "/var/lib/radicale"
30 "/home/bot"
31 "/var/vmail"
32 "/var/dkim"
33 "/var/sieve"
34 "/var/lib/heisenbridge"
35 # identity.key also lives in clan vars; the SQLite databases are
36 # dumped consistently to /var/backup/parley by the preHook.
37 "/var/lib/parley"
38 # WBO boards (paint.lassul.us). DynamicUser + StateDirectory make
39 # /var/lib/whitebophir only a symlink, so back up the real directory.
40 "/var/lib/private/whitebophir"
41 # paperless (paperless.lassul.us) documents, index and classifier; the
42 # SQLite database is dumped consistently to /var/backup by the preHook.
43 "/var/lib/paperless"
44 ];
45 exclude = [
46 "*.pyc"
47 "/home/bot/.cache"
48 "/home/bot/.nix-defexpr"
49 "/home/bot/.nix-profile"
50 "/var/lib/parley/*.db*"
51 "/var/lib/paperless/db.sqlite3*"
52 ];
53 repo = "u550643@u550643.your-storagebox.de:/./neoprism";
54 encryption.mode = "none";
55 compression = "auto,zstd";
56 startAt = "*-*-* 03:00:00";
57 environment.BORG_RSH =
58 let
59 knownHostsFile = pkgs.writeText "storagebox-known-hosts" ''
60 [u550643.your-storagebox.de]:23 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs
61 '';
62 in
63 "ssh -oPort=23 -oUserKnownHostsFile=${knownHostsFile} -i ${
64 config.clan.core.vars.generators.borgbackup.files."borgbackup.ssh.id25519".path
65 }";
66
67 readWritePaths = [
68 "/var/backup"
69 "/var/lib/hedgedoc"
70 # WAL-mode SQLite readers need to write the -shm file
71 "/var/lib/parley"
72 "/var/lib/paperless"
73 ];
74
75 preHook = ''
76 set -x
77 # Dump matrix-synapse PostgreSQL database (14GB, compresses well)
78 ${pkgs.sudo}/bin/sudo -u postgres ${config.services.postgresql.package}/bin/pg_dump \
79 matrix-synapse | ${pkgs.gzip}/bin/gzip > /var/backup/postgresql/matrix-synapse.sql.gz
80
81 # Dump bridge PostgreSQL databases — portal mappings, sessions, tokens.
82 # Losing these = relogin everywhere + every existing Matrix room orphaned.
83 for db in mautrix-whatsapp mautrix-signal mautrix-telegram mautrix-discord; do
84 ${pkgs.sudo}/bin/sudo -u postgres ${config.services.postgresql.package}/bin/pg_dump \
85 "$db" | ${pkgs.gzip}/bin/gzip > "/var/backup/postgresql/$db.sql.gz"
86 done
87
88 # Dump zitadel (id.lassul.us) PostgreSQL database: users, passkeys,
89 # IdP links, OIDC apps. Its secrets are encrypted with the masterkey
90 # from clan vars.
91 ${pkgs.sudo}/bin/sudo -u postgres ${config.services.postgresql.package}/bin/pg_dump \
92 zitadel | ${pkgs.gzip}/bin/gzip > /var/backup/postgresql/zitadel.sql.gz
93
94 # Dump hedgedoc SQLite database safely. It uses a rollback journal and
95 # writes often during the day, so wait for its locks instead of failing.
96 ${pkgs.sqlite}/bin/sqlite3 -cmd ".timeout 60000" /var/lib/hedgedoc/db.sqlite ".backup /var/backup/hedgedoc.sqlite"
97
98 # Dump parley accounts + history SQLite databases safely
99 for db in parley history; do
100 ${pkgs.sqlite}/bin/sqlite3 -cmd ".timeout 60000" "/var/lib/parley/$db.db" ".backup /var/backup/parley/$db.db"
101 done
102
103 # Dump paperless SQLite database safely
104 ${pkgs.sqlite}/bin/sqlite3 -cmd ".timeout 60000" /var/lib/paperless/db.sqlite3 ".backup /var/backup/paperless.sqlite3"
105
106 # Dump timeful polls (when.lassul.us) from MongoDB
107 ${pkgs.mongodb-tools}/bin/mongodump --uri=mongodb://127.0.0.1:27017 \
108 --db=schej-it --gzip --archive=/var/backup/timeful.archive.gz
109 '';
110
111 prune.keep = {
112 within = "1d";
113 daily = 7;
114 weekly = 4;
115 monthly = 0;
116 };
117 };
118}