diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2024-06-10 13:13:11 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2024-06-11 00:18:33 +0200 |
commit | 1c90c0dd73b5b74612be736ac8deeaa4547e2c26 (patch) | |
tree | 80a7bfcecd7478fb42c57616f706c90441475b88 /systems/eldiron | |
parent | e8d50f14185867d490f002aa5c408343ea5ea062 (diff) | |
download | Nix-1c90c0dd73b5b74612be736ac8deeaa4547e2c26.tar.gz Nix-1c90c0dd73b5b74612be736ac8deeaa4547e2c26.tar.zst Nix-1c90c0dd73b5b74612be736ac8deeaa4547e2c26.zip |
Migrate to borg backup
Diffstat (limited to 'systems/eldiron')
-rw-r--r-- | systems/eldiron/base.nix | 14 | ||||
-rw-r--r-- | systems/eldiron/borg_backup.nix | 241 | ||||
-rw-r--r-- | systems/eldiron/databases/openldap/default.nix | 3 | ||||
-rw-r--r-- | systems/eldiron/duply_backup.nix | 278 | ||||
-rw-r--r-- | systems/eldiron/flake.lock | 26 | ||||
-rw-r--r-- | systems/eldiron/ftp.nix | 4 | ||||
-rw-r--r-- | systems/eldiron/gitolite/default.nix | 16 | ||||
-rw-r--r-- | systems/eldiron/pub/default.nix | 3 | ||||
-rw-r--r-- | systems/eldiron/websites/cloud/default.nix | 9 | ||||
-rw-r--r-- | systems/eldiron/websites/commento/default.nix | 3 | ||||
-rw-r--r-- | systems/eldiron/websites/cryptpad/default.nix | 3 | ||||
-rw-r--r-- | systems/eldiron/websites/tools/default.nix | 15 |
12 files changed, 524 insertions, 91 deletions
diff --git a/systems/eldiron/base.nix b/systems/eldiron/base.nix index a77a438..5308ddb 100644 --- a/systems/eldiron/base.nix +++ b/systems/eldiron/base.nix | |||
@@ -118,6 +118,7 @@ | |||
118 | ./buildbot | 118 | ./buildbot |
119 | ./coturn.nix | 119 | ./coturn.nix |
120 | ./dns.nix | 120 | ./dns.nix |
121 | ./borg_backup.nix | ||
121 | ./duply_backup.nix | 122 | ./duply_backup.nix |
122 | ./gemini | 123 | ./gemini |
123 | ./gitolite | 124 | ./gitolite |
@@ -132,6 +133,19 @@ | |||
132 | ./vpn | 133 | ./vpn |
133 | ]; | 134 | ]; |
134 | 135 | ||
136 | services.borgBackup.enable = true; | ||
137 | services.borgBackup.profiles.global = { | ||
138 | bucket = "global"; | ||
139 | hash = false; | ||
140 | remotes = [ "attilax" ]; | ||
141 | ignoredPaths = [ | ||
142 | "udev" | ||
143 | "portables" | ||
144 | "machines" | ||
145 | "nixos" | ||
146 | "nixos-containers" | ||
147 | ]; | ||
148 | }; | ||
135 | myServices.buildbot.enable = true; | 149 | myServices.buildbot.enable = true; |
136 | myServices.databases.enable = true; | 150 | myServices.databases.enable = true; |
137 | myServices.gitolite.enable = true; | 151 | myServices.gitolite.enable = true; |
diff --git a/systems/eldiron/borg_backup.nix b/systems/eldiron/borg_backup.nix new file mode 100644 index 0000000..9956a46 --- /dev/null +++ b/systems/eldiron/borg_backup.nix | |||
@@ -0,0 +1,241 @@ | |||
1 | { lib, pkgs, config, name, ... }: | ||
2 | |||
3 | let | ||
4 | cfg = config.myEnv.borg_backup; | ||
5 | varDir = "/var/lib/borgbackup"; | ||
6 | borg_args = "--encryption repokey --make-parent-dirs init create prune compact check"; | ||
7 | borg_backup_full_with_ignored = pkgs.writeScriptBin "borg_full_with_ignored" '' | ||
8 | #!${pkgs.stdenv.shell} | ||
9 | |||
10 | if [ -z "$1" -o "$1" = "-h" -o "$1" = "--help" ]; then | ||
11 | echo "borg_full_with_ignored /path/to/borgmatic.yaml" | ||
12 | echo "Does a full backup including directories with .duplicity-ignore" | ||
13 | exit 1 | ||
14 | fi | ||
15 | ${pkgs.borgmatic}/bin/borgmatic -c "$1" --override 'storage.archive_name_format="{hostname}-with-ignored-{now:%Y-%m-%dT%H:%M:%S.%f}"' --override 'location.exclude_if_present=[]' ${borg_args} | ||
16 | ''; | ||
17 | borg_backup = pkgs.writeScriptBin "borg_backup" '' | ||
18 | #!${pkgs.stdenv.shell} | ||
19 | |||
20 | declare -a profiles | ||
21 | profiles=() | ||
22 | ${builtins.concatStringsSep "\n" (lib.flatten (lib.mapAttrsToList (k: v: map (remote: [ | ||
23 | ''profiles+=("${remote}_${k}")'' | ||
24 | ]) v.remotes) config.services.borgBackup.profiles))} | ||
25 | |||
26 | if [ -f "${varDir}/last_backup_profile" ]; then | ||
27 | last_backup=$(cat ${varDir}/last_backup_profile) | ||
28 | for i in "''${!profiles[@]}"; do | ||
29 | if [[ "''${profiles[$i]}" = "$last_backup" ]]; then | ||
30 | break | ||
31 | fi | ||
32 | done | ||
33 | ((i+=1)) | ||
34 | profiles=("''${profiles[@]:$i}" "''${profiles[@]:0:$i}") | ||
35 | fi | ||
36 | |||
37 | # timeout in minutes | ||
38 | timeout="''${1:-180}" | ||
39 | timeout_timestamp=$(date +%s -d "$timeout minutes") | ||
40 | for profile in "''${profiles[@]}"; do | ||
41 | if [ $(date +%s -d "now") -ge "$timeout_timestamp" ]; then | ||
42 | break | ||
43 | fi | ||
44 | |||
45 | touch "${varDir}/$profile.log" | ||
46 | ${pkgs.borgmatic}/bin/borgmatic -c "${config.secrets.location}/borg_backup/$profile/borgmatic.yaml" ${borg_args} >> ${varDir}/$profile.log | ||
47 | [[ $? = 0 ]] || echo -e "Error when doing backup for $profile, see above or logs in ${varDir}/$profile.log\n---------------------------------------" >&2 | ||
48 | echo "$profile" > ${varDir}/last_backup_profile | ||
49 | done | ||
50 | ''; | ||
51 | |||
52 | check_backups = pkgs.writeScriptBin "borg_list_not_backuped" '' | ||
53 | #!${pkgs.stdenv.shell} | ||
54 | |||
55 | do_check() { | ||
56 | local dir="$1" path ignored_path | ||
57 | find "$dir" -mindepth 1 -maxdepth 1 | while IFS= read -r path; do | ||
58 | if ${pkgs.gnugrep}/bin/grep -qFx "$path" ${config.secrets.fullPaths."borg_backup/backuped_list"}; then | ||
59 | continue | ||
60 | elif ${pkgs.gnugrep}/bin/grep -q "^$path/" ${config.secrets.fullPaths."borg_backup/backuped_list"}; then | ||
61 | do_check "$path" | ||
62 | else | ||
63 | while IFS= read -r ignored_path; do | ||
64 | if [[ "$path" =~ ^$ignored_path$ ]]; then | ||
65 | continue 2 | ||
66 | fi | ||
67 | done < ${config.secrets.fullPaths."borg_backup/ignored_list"} | ||
68 | printf '%s\n' "$path" | ||
69 | fi | ||
70 | done | ||
71 | } | ||
72 | |||
73 | do_check /var/lib | ||
74 | ''; | ||
75 | borgProfile = profile: remote: bucket: builtins.toJSON { | ||
76 | location = { | ||
77 | source_directories = map (p: "${profile.rootDir}/${p}") profile.includedPaths; | ||
78 | repositories = [ | ||
79 | { path = cfg.remotes.${remote}.remote bucket; label = "backupserver"; } | ||
80 | ]; | ||
81 | one_file_system = false; | ||
82 | exclude_if_present = [".duplicity-ignore"]; | ||
83 | source_directories_must_exist = profile.directoriesMustExist; | ||
84 | borgmatic_source_directory = "${varDir}/${profile.bucket}/.borgmatic"; | ||
85 | }; | ||
86 | storage = { | ||
87 | encryption_passphrase = profile.password; | ||
88 | ssh_command = "ssh -i ${config.secrets.fullPaths."borg_backup/identity"}"; | ||
89 | compression = "zlib"; | ||
90 | borg_base_directory = "${varDir}/${profile.bucket}"; | ||
91 | }; | ||
92 | retention = { | ||
93 | keep_within = "10d"; | ||
94 | keep_daily = 30; | ||
95 | }; | ||
96 | }; | ||
97 | in | ||
98 | { | ||
99 | options = { | ||
100 | services.borgBackup.enable = lib.mkOption { | ||
101 | type = lib.types.bool; | ||
102 | default = false; | ||
103 | description = '' | ||
104 | Whether to enable remote backups. | ||
105 | ''; | ||
106 | }; | ||
107 | services.borgBackup.profiles = lib.mkOption { | ||
108 | type = lib.types.attrsOf (lib.types.submodule { | ||
109 | options = { | ||
110 | hash = lib.mkOption { | ||
111 | type = lib.types.bool; | ||
112 | default = true; | ||
113 | description = '' | ||
114 | Hash bucket and directory names | ||
115 | ''; | ||
116 | }; | ||
117 | rootDir = lib.mkOption { | ||
118 | type = lib.types.path; | ||
119 | default = "/var/lib"; | ||
120 | description = '' | ||
121 | Path to backup | ||
122 | ''; | ||
123 | }; | ||
124 | password = lib.mkOption { | ||
125 | type = lib.types.str; | ||
126 | default = cfg.password; | ||
127 | description = '' | ||
128 | password to use to encrypt data | ||
129 | ''; | ||
130 | }; | ||
131 | directoriesMustExist = lib.mkOption { | ||
132 | type = lib.types.bool; | ||
133 | default = true; | ||
134 | description = '' | ||
135 | Raise error if backuped directory doesn't exist | ||
136 | ''; | ||
137 | }; | ||
138 | bucket = lib.mkOption { | ||
139 | type = lib.types.str; | ||
140 | description = '' | ||
141 | Bucket to use | ||
142 | ''; | ||
143 | }; | ||
144 | remotes = lib.mkOption { | ||
145 | type = lib.types.listOf lib.types.str; | ||
146 | description = '' | ||
147 | Remotes to use for backup | ||
148 | ''; | ||
149 | }; | ||
150 | includedPaths = lib.mkOption { | ||
151 | type = lib.types.listOf lib.types.str; | ||
152 | default = []; | ||
153 | description = '' | ||
154 | Included paths (subdirs of rootDir) | ||
155 | ''; | ||
156 | }; | ||
157 | excludeFile = lib.mkOption { | ||
158 | type = lib.types.lines; | ||
159 | default = ""; | ||
160 | description = '' | ||
161 | Content to put in exclude file | ||
162 | ''; | ||
163 | }; | ||
164 | ignoredPaths = lib.mkOption { | ||
165 | type = lib.types.listOf lib.types.str; | ||
166 | default = []; | ||
167 | description = '' | ||
168 | List of paths to ignore when checking non-backed-up directories | ||
169 | Can use (POSIX extended) regex | ||
170 | ''; | ||
171 | }; | ||
172 | }; | ||
173 | }); | ||
174 | }; | ||
175 | }; | ||
176 | |||
177 | config = lib.mkIf config.services.borgBackup.enable { | ||
178 | system.activationScripts.borg_backup = '' | ||
179 | install -m 0700 -o root -g root -d ${varDir} | ||
180 | ''; | ||
181 | secrets.keys = lib.listToAttrs (lib.flatten (lib.mapAttrsToList (k: v: | ||
182 | let | ||
183 | bucket = if v.hash or true then builtins.hashString "sha256" v.bucket else v.bucket; | ||
184 | in map (remote: [ | ||
185 | (lib.nameValuePair "borg_backup/${remote}_${k}/borgmatic.yaml" { | ||
186 | permissions = "0400"; | ||
187 | text = borgProfile v remote bucket; | ||
188 | }) | ||
189 | (lib.nameValuePair "borg_backup/${remote}_${k}" { | ||
190 | permissions = "0700"; | ||
191 | isDir = true; | ||
192 | }) | ||
193 | ]) v.remotes) config.services.borgBackup.profiles)) // { | ||
194 | "borg_backup/identity" = { | ||
195 | permissions = "0400"; | ||
196 | text = "{{ .ssl_keys.borg_backup }}"; | ||
197 | }; | ||
198 | "borg_backup/ignored_list" = { | ||
199 | permissions = "0400"; | ||
200 | text = let | ||
201 | ignored = map | ||
202 | (v: map (p: "${v.rootDir}/${p}") v.ignoredPaths) | ||
203 | (builtins.attrValues config.services.borgBackup.profiles); | ||
204 | in builtins.concatStringsSep "\n" (lib.flatten ignored); | ||
205 | }; | ||
206 | "borg_backup/backuped_list" = { | ||
207 | permissions = "0400"; | ||
208 | text = let | ||
209 | included = map | ||
210 | (v: map (p: "${v.rootDir}/${p}") v.includedPaths) | ||
211 | (builtins.attrValues config.services.borgBackup.profiles); | ||
212 | in builtins.concatStringsSep "\n" (lib.flatten included); | ||
213 | }; | ||
214 | }; | ||
215 | |||
216 | programs.ssh.knownHostsFiles = [ | ||
217 | (pkgs.writeText | ||
218 | "borg_backup_known_hosts" | ||
219 | (builtins.concatStringsSep | ||
220 | "\n" | ||
221 | (builtins.filter | ||
222 | (v: v != null) | ||
223 | (builtins.map | ||
224 | (v: v.sshKnownHosts) | ||
225 | (builtins.attrValues cfg.remotes) | ||
226 | ) | ||
227 | ) | ||
228 | ) | ||
229 | ) | ||
230 | ]; | ||
231 | environment.systemPackages = [ pkgs.borgbackup pkgs.borgmatic borg_backup_full_with_ignored borg_backup check_backups ]; | ||
232 | services.cron = { | ||
233 | enable = true; | ||
234 | systemCronJobs = [ | ||
235 | "0 0 * * * root ${borg_backup}/bin/borg_backup 300" | ||
236 | ]; | ||
237 | |||
238 | }; | ||
239 | |||
240 | }; | ||
241 | } | ||
diff --git a/systems/eldiron/databases/openldap/default.nix b/systems/eldiron/databases/openldap/default.nix index 7cd15da..fcab337 100644 --- a/systems/eldiron/databases/openldap/default.nix +++ b/systems/eldiron/databases/openldap/default.nix | |||
@@ -103,6 +103,9 @@ in | |||
103 | }; | 103 | }; |
104 | users.users.openldap.extraGroups = [ "keys" ]; | 104 | users.users.openldap.extraGroups = [ "keys" ]; |
105 | networking.firewall.allowedTCPPorts = [ 636 389 ]; | 105 | networking.firewall.allowedTCPPorts = [ 636 389 ]; |
106 | services.borgBackup.profiles.global.includedPaths = [ | ||
107 | "openldap" | ||
108 | ]; | ||
106 | 109 | ||
107 | security.acme.certs."ldap" = { | 110 | security.acme.certs."ldap" = { |
108 | group = "openldap"; | 111 | group = "openldap"; |
diff --git a/systems/eldiron/duply_backup.nix b/systems/eldiron/duply_backup.nix index 590d125..5143302 100644 --- a/systems/eldiron/duply_backup.nix +++ b/systems/eldiron/duply_backup.nix | |||
@@ -3,29 +3,108 @@ | |||
3 | let | 3 | let |
4 | cfg = config.myEnv.backup; | 4 | cfg = config.myEnv.backup; |
5 | varDir = "/var/lib/duply"; | 5 | varDir = "/var/lib/duply"; |
6 | duplyProfile = profile: remote: prefix: '' | 6 | default_action = "pre_bkp_purge_purgeFull_purgeIncr"; |
7 | GPG_PW="${cfg.password}" | 7 | duply_backup_full_with_ignored = pkgs.writeScriptBin "duply_full_with_ignored" '' |
8 | TARGET="${cfg.remotes.${remote}.remote profile.bucket}${prefix}" | 8 | #!${pkgs.stdenv.shell} |
9 | export AWS_ACCESS_KEY_ID="${cfg.remotes.${remote}.accessKeyId}" | 9 | |
10 | export AWS_SECRET_ACCESS_KEY="${cfg.remotes.${remote}.secretAccessKey}" | 10 | export DUPLY_FULL_BACKUP_WITH_IGNORED=yes |
11 | if [ -z "$1" -o "$1" = "-h" -o "$1" = "--help" ]; then | ||
12 | echo "duply_full_with_ignored /path/to/profile" | ||
13 | echo "Does a full backup including directories with .duplicity-ignore" | ||
14 | exit 1 | ||
15 | fi | ||
16 | ${pkgs.duply}/bin/duply "$1" pre_full --force | ||
17 | ''; | ||
18 | duply_backup = pkgs.writeScriptBin "duply_backup" '' | ||
19 | #!${pkgs.stdenv.shell} | ||
20 | |||
21 | declare -a profiles | ||
22 | profiles=() | ||
23 | ${builtins.concatStringsSep "\n" (lib.flatten (lib.mapAttrsToList (k: v: map (remote: [ | ||
24 | ''profiles+=("${remote}_${k}")'' | ||
25 | ]) v.remotes) config.services.duplyBackup.profiles))} | ||
26 | |||
27 | if [ -f "${varDir}/last_backup_profile" ]; then | ||
28 | last_backup=$(cat ${varDir}/last_backup_profile) | ||
29 | for i in "''${!profiles[@]}"; do | ||
30 | if [[ "''${profiles[$i]}" = "$last_backup" ]]; then | ||
31 | break | ||
32 | fi | ||
33 | done | ||
34 | ((i+=1)) | ||
35 | profiles=("''${profiles[@]:$i}" "''${profiles[@]:0:$i}") | ||
36 | fi | ||
37 | |||
38 | # timeout in minutes | ||
39 | timeout="''${1:-180}" | ||
40 | timeout_timestamp=$(date +%s -d "$timeout minutes") | ||
41 | for profile in "''${profiles[@]}"; do | ||
42 | if [ $(date +%s -d "now") -ge "$timeout_timestamp" ]; then | ||
43 | break | ||
44 | fi | ||
45 | |||
46 | touch "${varDir}/$profile.log" | ||
47 | ${pkgs.duply}/bin/duply ${config.secrets.location}/backup/$profile/ ${default_action} --force >> ${varDir}/$profile.log | ||
48 | [[ $? = 0 ]] || echo -e "Error when doing backup for $profile, see above or logs in ${varDir}/$profile.log\n---------------------------------------" >&2 | ||
49 | echo "$profile" > ${varDir}/last_backup_profile | ||
50 | done | ||
51 | ''; | ||
52 | |||
53 | check_backups = pkgs.writeScriptBin "duply_list_not_backuped" '' | ||
54 | #!${pkgs.stdenv.shell} | ||
55 | |||
56 | do_check() { | ||
57 | local dir="$1" path ignored_path | ||
58 | find "$dir" -mindepth 1 -maxdepth 1 | while IFS= read -r path; do | ||
59 | if ${pkgs.gnugrep}/bin/grep -qFx "$path" ${config.secrets.fullPaths."backup/backuped_list"}; then | ||
60 | continue | ||
61 | elif ${pkgs.gnugrep}/bin/grep -q "^$path/" ${config.secrets.fullPaths."backup/backuped_list"}; then | ||
62 | do_check "$path" | ||
63 | else | ||
64 | while IFS= read -r ignored_path; do | ||
65 | if [[ "$path" =~ ^$ignored_path$ ]]; then | ||
66 | continue 2 | ||
67 | fi | ||
68 | done < ${config.secrets.fullPaths."backup/ignored_list"} | ||
69 | printf '%s\n' "$path" | ||
70 | fi | ||
71 | done | ||
72 | } | ||
73 | |||
74 | do_check /var/lib | ||
75 | ''; | ||
76 | duplyProfile = profile: remote: bucket: let | ||
77 | remote' = cfg.remotes.${remote}; | ||
78 | in '' | ||
79 | if [ -z "$DUPLY_FULL_BACKUP_WITH_IGNORED" ]; then | ||
80 | GPG_PW="${cfg.password}" | ||
81 | fi | ||
82 | TARGET="${remote'.remote bucket}" | ||
83 | ${lib.optionalString (remote'.remote_type == "s3") '' | ||
84 | export AWS_ACCESS_KEY_ID="${remote'.s3AccessKeyId}" | ||
85 | export AWS_SECRET_ACCESS_KEY="${remote'.s3SecretAccessKey}" | ||
86 | ''} | ||
87 | ${lib.optionalString (remote'.remote_type == "rsync") '' | ||
88 | DUPL_PARAMS="$DUPL_PARAMS --ssh-options=-oIdentityFile='${config.secrets.fullPaths."backup/identity"}' " | ||
89 | ''} | ||
11 | SOURCE="${profile.rootDir}" | 90 | SOURCE="${profile.rootDir}" |
12 | FILENAME=".duplicity-ignore" | 91 | if [ -z "$DUPLY_FULL_BACKUP_WITH_IGNORED" ]; then |
13 | DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'" | 92 | FILENAME=".duplicity-ignore" |
93 | DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'" | ||
94 | fi | ||
14 | VERBOSITY=4 | 95 | VERBOSITY=4 |
15 | ARCH_DIR="${varDir}/caches" | 96 | ARCH_DIR="${varDir}/caches" |
97 | DUPL_PYTHON_BIN="" | ||
16 | 98 | ||
17 | # Do a full backup after 1 month | 99 | # Do a full backup after 6 month |
18 | MAX_FULLBKP_AGE=1M | 100 | MAX_FULLBKP_AGE=6M |
19 | DUPL_PARAMS="$DUPL_PARAMS --allow-source-mismatch --exclude-other-filesystems --full-if-older-than $MAX_FULLBKP_AGE " | 101 | DUPL_PARAMS="$DUPL_PARAMS --allow-source-mismatch --full-if-older-than $MAX_FULLBKP_AGE " |
20 | # Backups older than 2months are deleted | 102 | # Backups older than 1months are deleted |
21 | MAX_AGE=2M | 103 | MAX_AGE=1M |
22 | # Keep 2 full backups | 104 | # Keep 1 full backup |
23 | MAX_FULL_BACKUPS=2 | 105 | MAX_FULL_BACKUPS=1 |
24 | MAX_FULLS_WITH_INCRS=2 | 106 | MAX_FULLS_WITH_INCRS=1 |
25 | ''; | 107 | ''; |
26 | action = "bkp_purge_purgeFull_purgeIncr"; | ||
27 | varName = k: remoteName: | ||
28 | if remoteName == "eriomem" then k else remoteName + "_" + k; | ||
29 | in | 108 | in |
30 | { | 109 | { |
31 | options = { | 110 | options = { |
@@ -39,26 +118,46 @@ in | |||
39 | services.duplyBackup.profiles = lib.mkOption { | 118 | services.duplyBackup.profiles = lib.mkOption { |
40 | type = lib.types.attrsOf (lib.types.submodule { | 119 | type = lib.types.attrsOf (lib.types.submodule { |
41 | options = { | 120 | options = { |
121 | hash = lib.mkOption { | ||
122 | type = lib.types.bool; | ||
123 | default = true; | ||
124 | description = '' | ||
125 | Hash bucket and directory names | ||
126 | ''; | ||
127 | }; | ||
128 | excludeRootDir = lib.mkOption { | ||
129 | type = lib.types.bool; | ||
130 | default = true; | ||
131 | description = '' | ||
132 | Exclude root dir in exclusion file | ||
133 | ''; | ||
134 | }; | ||
42 | rootDir = lib.mkOption { | 135 | rootDir = lib.mkOption { |
43 | type = lib.types.path; | 136 | type = lib.types.path; |
137 | default = "/var/lib"; | ||
44 | description = '' | 138 | description = '' |
45 | Path to backup | 139 | Path to backup |
46 | ''; | 140 | ''; |
47 | }; | 141 | }; |
48 | bucket = lib.mkOption { | 142 | bucket = lib.mkOption { |
49 | type = lib.types.str; | 143 | type = lib.types.str; |
50 | default = "immae-${name}"; | ||
51 | description = '' | 144 | description = '' |
52 | Bucket to use | 145 | Bucket to use |
53 | ''; | 146 | ''; |
54 | }; | 147 | }; |
55 | remotes = lib.mkOption { | 148 | remotes = lib.mkOption { |
56 | type = lib.types.listOf lib.types.str; | 149 | type = lib.types.listOf lib.types.str; |
57 | default = ["eriomem"]; | ||
58 | description = '' | 150 | description = '' |
59 | Remotes to use for backup | 151 | Remotes to use for backup |
60 | ''; | 152 | ''; |
61 | }; | 153 | }; |
154 | includedPaths = lib.mkOption { | ||
155 | type = lib.types.listOf lib.types.str; | ||
156 | default = []; | ||
157 | description = '' | ||
158 | Included paths (subdirs of rootDir) | ||
159 | ''; | ||
160 | }; | ||
62 | excludeFile = lib.mkOption { | 161 | excludeFile = lib.mkOption { |
63 | type = lib.types.lines; | 162 | type = lib.types.lines; |
64 | default = ""; | 163 | default = ""; |
@@ -66,6 +165,14 @@ in | |||
66 | Content to put in exclude file | 165 | Content to put in exclude file |
67 | ''; | 166 | ''; |
68 | }; | 167 | }; |
168 | ignoredPaths = lib.mkOption { | ||
169 | type = lib.types.listOf lib.types.str; | ||
170 | default = []; | ||
171 | description = '' | ||
172 | List of paths to ignore when checking non-backed-up directories | ||
173 | Can use (POSIX extended) regex | ||
174 | ''; | ||
175 | }; | ||
69 | }; | 176 | }; |
70 | }); | 177 | }); |
71 | }; | 178 | }; |
@@ -76,76 +183,91 @@ in | |||
76 | install -m 0700 -o root -g root -d ${varDir} ${varDir}/caches | 183 | install -m 0700 -o root -g root -d ${varDir} ${varDir}/caches |
77 | ''; | 184 | ''; |
78 | secrets.keys = lib.listToAttrs (lib.flatten (lib.mapAttrsToList (k: v: | 185 | secrets.keys = lib.listToAttrs (lib.flatten (lib.mapAttrsToList (k: v: |
79 | map (remote: [ | 186 | let |
80 | (lib.nameValuePair "backup/${varName k remote}/conf" { | 187 | bucket = if v.hash or true then builtins.hashString "sha256" v.bucket else v.bucket; |
188 | in map (remote: [ | ||
189 | (lib.nameValuePair "backup/${remote}_${k}/conf" { | ||
81 | permissions = "0400"; | 190 | permissions = "0400"; |
82 | text = duplyProfile v remote "${k}/"; | 191 | text = duplyProfile v remote bucket; |
83 | }) | 192 | }) |
84 | (lib.nameValuePair "backup/${varName k remote}/exclude" { | 193 | (lib.nameValuePair "backup/${remote}_${k}/exclude" { |
85 | permissions = "0400"; | 194 | permissions = "0400"; |
86 | text = v.excludeFile; | 195 | text = v.excludeFile + (builtins.concatStringsSep "\n" (map (p: "+ ${v.rootDir}/${p}") v.includedPaths)) + (lib.optionalString v.excludeRootDir '' |
196 | |||
197 | - ** | ||
198 | ''); | ||
87 | }) | 199 | }) |
88 | (lib.nameValuePair "backup/${varName k remote}" { | 200 | (lib.nameValuePair "backup/${remote}_${k}/pre" { |
201 | keyDependencies = [ | ||
202 | pkgs.bash | ||
203 | pkgs.rsync | ||
204 | ]; | ||
89 | permissions = "0500"; | 205 | permissions = "0500"; |
206 | text = let | ||
207 | remote' = cfg.remotes.${remote}; | ||
208 | in '' | ||
209 | #!${pkgs.stdenv.shell} | ||
210 | |||
211 | ${lib.optionalString (remote'.remote_type == "rsync") '' | ||
212 | # Recreate directory structure before synchronizing | ||
213 | mkdir -p ${varDir}/rsync_remotes/${remote}/${bucket} | ||
214 | ${pkgs.rsync}/bin/rsync -av -e \ | ||
215 | "ssh -p ${remote'.sshRsyncPort} -oIdentityFile=${config.secrets.fullPaths."backup/identity"}" \ | ||
216 | "${varDir}/rsync_remotes/${remote}/" \ | ||
217 | ${remote'.sshRsyncHost}: | ||
218 | ''} | ||
219 | ''; | ||
220 | }) | ||
221 | (lib.nameValuePair "backup/${remote}_${k}" { | ||
222 | permissions = "0700"; | ||
90 | isDir = true; | 223 | isDir = true; |
91 | }) | 224 | }) |
92 | ]) v.remotes) config.services.duplyBackup.profiles)); | 225 | ]) v.remotes) config.services.duplyBackup.profiles)) // { |
226 | "backup/identity" = { | ||
227 | permissions = "0400"; | ||
228 | text = "{{ .ssl_keys.duply_backup }}"; | ||
229 | }; | ||
230 | "backup/ignored_list" = { | ||
231 | permissions = "0400"; | ||
232 | text = let | ||
233 | ignored = map | ||
234 | (v: map (p: "${v.rootDir}/${p}") v.ignoredPaths) | ||
235 | (builtins.attrValues config.services.duplyBackup.profiles); | ||
236 | in builtins.concatStringsSep "\n" (lib.flatten ignored); | ||
237 | }; | ||
238 | "backup/backuped_list" = { | ||
239 | permissions = "0400"; | ||
240 | text = let | ||
241 | included = map | ||
242 | (v: map (p: "${v.rootDir}/${p}") v.includedPaths) | ||
243 | (builtins.attrValues config.services.duplyBackup.profiles); | ||
244 | in builtins.concatStringsSep "\n" (lib.flatten included); | ||
245 | }; | ||
246 | }; | ||
93 | 247 | ||
248 | programs.ssh.knownHostsFiles = [ | ||
249 | (pkgs.writeText | ||
250 | "duply_backup_known_hosts" | ||
251 | (builtins.concatStringsSep | ||
252 | "\n" | ||
253 | (builtins.filter | ||
254 | (v: v != null) | ||
255 | (builtins.map | ||
256 | (v: v.sshKnownHosts) | ||
257 | (builtins.attrValues cfg.remotes) | ||
258 | ) | ||
259 | ) | ||
260 | ) | ||
261 | ) | ||
262 | ]; | ||
263 | environment.systemPackages = [ pkgs.duply check_backups duply_backup_full_with_ignored duply_backup ]; | ||
94 | services.cron = { | 264 | services.cron = { |
95 | enable = true; | 265 | enable = true; |
96 | systemCronJobs = let | 266 | systemCronJobs = [ |
97 | backups = pkgs.writeScript "backups" '' | 267 | "0 0 * * * root ${duply_backup}/bin/duply_backup 90" |
98 | #!${pkgs.stdenv.shell} | 268 | ]; |
99 | |||
100 | ${builtins.concatStringsSep "\n" (lib.flatten (lib.mapAttrsToList (k: v: | ||
101 | map (remote: [ | ||
102 | '' | ||
103 | touch ${varDir}/${varName k remote}.log | ||
104 | ${pkgs.duply}/bin/duply ${config.secrets.fullPaths."backup/${varName k remote}"}/ ${action} --force >> ${varDir}/${varName k remote}.log | ||
105 | [[ $? = 0 ]] || echo -e "Error when doing backup for ${varName k remote}, see above\n---------------------------------------" >&2 | ||
106 | '' | ||
107 | ]) v.remotes | ||
108 | ) config.services.duplyBackup.profiles))} | ||
109 | ''; | ||
110 | in | ||
111 | [ | ||
112 | "0 2 * * * root ${backups}" | ||
113 | ]; | ||
114 | 269 | ||
115 | }; | 270 | }; |
116 | 271 | ||
117 | security.pki.certificateFiles = [ | ||
118 | (pkgs.fetchurl { | ||
119 | url = "http://downloads.e.eriomem.net/eriomemca.pem"; | ||
120 | sha256 = "1ixx4c6j3m26j8dp9a3dkvxc80v1nr5aqgmawwgs06bskasqkvvh"; | ||
121 | }) | ||
122 | ]; | ||
123 | |||
124 | myServices.monitoring.fromMasterActivatedPlugins = [ "eriomem" ]; | ||
125 | myServices.monitoring.fromMasterObjects.service = [ | ||
126 | { | ||
127 | service_description = "eriomem backup is up and not full"; | ||
128 | host_name = config.hostEnv.fqdn; | ||
129 | use = "external-service"; | ||
130 | check_command = "check_backup_eriomem"; | ||
131 | |||
132 | check_interval = 120; | ||
133 | notification_interval = "1440"; | ||
134 | |||
135 | servicegroups = "webstatus-backup"; | ||
136 | } | ||
137 | |||
138 | { | ||
139 | service_description = "ovh backup is up and not full"; | ||
140 | host_name = config.hostEnv.fqdn; | ||
141 | use = "external-service"; | ||
142 | check_command = "check_ok"; | ||
143 | |||
144 | check_interval = 120; | ||
145 | notification_interval = "1440"; | ||
146 | |||
147 | servicegroups = "webstatus-backup"; | ||
148 | } | ||
149 | ]; | ||
150 | }; | 272 | }; |
151 | } | 273 | } |
diff --git a/systems/eldiron/flake.lock b/systems/eldiron/flake.lock index 27d4d5b..58291c5 100644 --- a/systems/eldiron/flake.lock +++ b/systems/eldiron/flake.lock | |||
@@ -129,7 +129,7 @@ | |||
129 | "environment": { | 129 | "environment": { |
130 | "locked": { | 130 | "locked": { |
131 | "lastModified": 1, | 131 | "lastModified": 1, |
132 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 132 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
133 | "path": "../environment", | 133 | "path": "../environment", |
134 | "type": "path" | 134 | "type": "path" |
135 | }, | 135 | }, |
@@ -141,7 +141,7 @@ | |||
141 | "environment_2": { | 141 | "environment_2": { |
142 | "locked": { | 142 | "locked": { |
143 | "lastModified": 1, | 143 | "lastModified": 1, |
144 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 144 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
145 | "path": "../environment", | 145 | "path": "../environment", |
146 | "type": "path" | 146 | "type": "path" |
147 | }, | 147 | }, |
@@ -153,7 +153,7 @@ | |||
153 | "environment_3": { | 153 | "environment_3": { |
154 | "locked": { | 154 | "locked": { |
155 | "lastModified": 1, | 155 | "lastModified": 1, |
156 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 156 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
157 | "path": "../environment", | 157 | "path": "../environment", |
158 | "type": "path" | 158 | "type": "path" |
159 | }, | 159 | }, |
@@ -165,7 +165,7 @@ | |||
165 | "environment_4": { | 165 | "environment_4": { |
166 | "locked": { | 166 | "locked": { |
167 | "lastModified": 1, | 167 | "lastModified": 1, |
168 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 168 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
169 | "path": "../environment", | 169 | "path": "../environment", |
170 | "type": "path" | 170 | "type": "path" |
171 | }, | 171 | }, |
@@ -177,7 +177,7 @@ | |||
177 | "environment_5": { | 177 | "environment_5": { |
178 | "locked": { | 178 | "locked": { |
179 | "lastModified": 1, | 179 | "lastModified": 1, |
180 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 180 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
181 | "path": "../environment", | 181 | "path": "../environment", |
182 | "type": "path" | 182 | "type": "path" |
183 | }, | 183 | }, |
@@ -189,7 +189,7 @@ | |||
189 | "environment_6": { | 189 | "environment_6": { |
190 | "locked": { | 190 | "locked": { |
191 | "lastModified": 1, | 191 | "lastModified": 1, |
192 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 192 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
193 | "path": "../environment", | 193 | "path": "../environment", |
194 | "type": "path" | 194 | "type": "path" |
195 | }, | 195 | }, |
@@ -1989,7 +1989,7 @@ | |||
1989 | }, | 1989 | }, |
1990 | "locked": { | 1990 | "locked": { |
1991 | "lastModified": 1, | 1991 | "lastModified": 1, |
1992 | "narHash": "sha256-ptLDqa3BTCX2orio9YgGsOwYa5bsz2DWn6TrtR2B45w=", | 1992 | "narHash": "sha256-Deh1qsi1UFskPSAwq2sUGyPeh7hVVHct8hhy4o6fEzE=", |
1993 | "path": "../../flakes/private/chatons", | 1993 | "path": "../../flakes/private/chatons", |
1994 | "type": "path" | 1994 | "type": "path" |
1995 | }, | 1995 | }, |
@@ -2001,7 +2001,7 @@ | |||
2001 | "private-environment": { | 2001 | "private-environment": { |
2002 | "locked": { | 2002 | "locked": { |
2003 | "lastModified": 1, | 2003 | "lastModified": 1, |
2004 | "narHash": "sha256-VO82m/95IcX3xxJ63wcLh3hXzXDRFKUohYil/18pBSY=", | 2004 | "narHash": "sha256-Kj3j/3B8V8IHbeSZ3ho33C7ktOcTle2h6dKEWWfVuvU=", |
2005 | "path": "../../flakes/private/environment", | 2005 | "path": "../../flakes/private/environment", |
2006 | "type": "path" | 2006 | "type": "path" |
2007 | }, | 2007 | }, |
@@ -2020,7 +2020,7 @@ | |||
2020 | }, | 2020 | }, |
2021 | "locked": { | 2021 | "locked": { |
2022 | "lastModified": 1, | 2022 | "lastModified": 1, |
2023 | "narHash": "sha256-VhRXb3AAlSKwkq4BfVmoKzkLxEaAFGjYLAFETTZuhjE=", | 2023 | "narHash": "sha256-bWNhkERypwoog3lphO0xURJ4xt58CZEWKn7So7A5mtM=", |
2024 | "path": "../../flakes/private/milters", | 2024 | "path": "../../flakes/private/milters", |
2025 | "type": "path" | 2025 | "type": "path" |
2026 | }, | 2026 | }, |
@@ -2038,7 +2038,7 @@ | |||
2038 | }, | 2038 | }, |
2039 | "locked": { | 2039 | "locked": { |
2040 | "lastModified": 1, | 2040 | "lastModified": 1, |
2041 | "narHash": "sha256-Lpe56lKWhlMQiQoCgvMJuqJtJ8+szDldjqMAGyt2U3U=", | 2041 | "narHash": "sha256-VZjf9fXcyeS3LpVW6NvzJpiJuEtJsGlOOfH8XwL8CdI=", |
2042 | "path": "../../flakes/private/monitoring", | 2042 | "path": "../../flakes/private/monitoring", |
2043 | "type": "path" | 2043 | "type": "path" |
2044 | }, | 2044 | }, |
@@ -2073,7 +2073,7 @@ | |||
2073 | }, | 2073 | }, |
2074 | "locked": { | 2074 | "locked": { |
2075 | "lastModified": 1, | 2075 | "lastModified": 1, |
2076 | "narHash": "sha256-/vQ6FGFc53r79yiQrzF0NWTbRd4RKf8QiPSDhmiCciU=", | 2076 | "narHash": "sha256-fntajNe0urhuR0NbTOQZLTMhtHnd7p6PVuuEf0oAoFg=", |
2077 | "path": "../../flakes/private/opendmarc", | 2077 | "path": "../../flakes/private/opendmarc", |
2078 | "type": "path" | 2078 | "type": "path" |
2079 | }, | 2079 | }, |
@@ -2134,7 +2134,7 @@ | |||
2134 | }, | 2134 | }, |
2135 | "locked": { | 2135 | "locked": { |
2136 | "lastModified": 1, | 2136 | "lastModified": 1, |
2137 | "narHash": "sha256-gjapO6CZFeLMHUlhqBVZu5P+IJzJaPu4pnuTep4ZSuM=", | 2137 | "narHash": "sha256-uqftr7R3cVYwWuu8Xl6VbPVL2pqapv1bfmMJpq3LnZ4=", |
2138 | "path": "../../flakes/private/ssh", | 2138 | "path": "../../flakes/private/ssh", |
2139 | "type": "path" | 2139 | "type": "path" |
2140 | }, | 2140 | }, |
@@ -2153,7 +2153,7 @@ | |||
2153 | }, | 2153 | }, |
2154 | "locked": { | 2154 | "locked": { |
2155 | "lastModified": 1, | 2155 | "lastModified": 1, |
2156 | "narHash": "sha256-+s9C1mPCXRA44AC0Fg+B2uD6UiK0JfUA0F8fhceH0lQ=", | 2156 | "narHash": "sha256-ufaclDTTnoB7xLOCOY4EretrBp70rSmk0YzcVfglbLA=", |
2157 | "path": "../../flakes/private/system", | 2157 | "path": "../../flakes/private/system", |
2158 | "type": "path" | 2158 | "type": "path" |
2159 | }, | 2159 | }, |
diff --git a/systems/eldiron/ftp.nix b/systems/eldiron/ftp.nix index 6aa1afc..e5bc0f5 100644 --- a/systems/eldiron/ftp.nix +++ b/systems/eldiron/ftp.nix | |||
@@ -30,6 +30,10 @@ in | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | config = lib.mkIf config.myServices.ftp.enable { | 32 | config = lib.mkIf config.myServices.ftp.enable { |
33 | services.borgBackup.profiles.global.ignoredPaths = [ | ||
34 | "ftp/test_ftp" | ||
35 | "proftpd/authorized_keys" | ||
36 | ]; | ||
33 | myServices.dns.zones."immae.eu".subdomains.ftp = | 37 | myServices.dns.zones."immae.eu".subdomains.ftp = |
34 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | 38 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; |
35 | 39 | ||
diff --git a/systems/eldiron/gitolite/default.nix b/systems/eldiron/gitolite/default.nix index 1885234..0882c18 100644 --- a/systems/eldiron/gitolite/default.nix +++ b/systems/eldiron/gitolite/default.nix | |||
@@ -11,6 +11,22 @@ in { | |||
11 | }; | 11 | }; |
12 | 12 | ||
13 | config = lib.mkIf cfg.enable { | 13 | config = lib.mkIf cfg.enable { |
14 | services.borgBackup.profiles.global.ignoredPaths = [ | ||
15 | "gitolite/.nix-.*" | ||
16 | "gitolite/.ssh" | ||
17 | "gitolite/.vim.*" | ||
18 | "gitolite/.bash_history" | ||
19 | ]; | ||
20 | services.borgBackup.profiles.global.includedPaths = [ | ||
21 | "gitolite/gitolite_ldap_groups.sh" | ||
22 | "gitolite/projects.list" | ||
23 | "gitolite/.gitolite.rc" | ||
24 | "gitolite/.gitolite" | ||
25 | "gitolite/repositories/github" | ||
26 | "gitolite/repositories/testing.git" | ||
27 | "gitolite/repositories/gitolite-admin.git" | ||
28 | |||
29 | ]; | ||
14 | myServices.dns.zones."immae.eu".subdomains.git = | 30 | myServices.dns.zones."immae.eu".subdomains.git = |
15 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | 31 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; |
16 | 32 | ||
diff --git a/systems/eldiron/pub/default.nix b/systems/eldiron/pub/default.nix index ca8122a..847e9d0 100644 --- a/systems/eldiron/pub/default.nix +++ b/systems/eldiron/pub/default.nix | |||
@@ -40,6 +40,9 @@ in | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | config = lib.mkIf config.myServices.pub.enable { | 42 | config = lib.mkIf config.myServices.pub.enable { |
43 | services.borgBackup.profiles.global.ignoredPaths = [ | ||
44 | "pub/.nix-.*" | ||
45 | ]; | ||
43 | myServices.dns.zones."immae.eu".subdomains.pub = | 46 | myServices.dns.zones."immae.eu".subdomains.pub = |
44 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | 47 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; |
45 | 48 | ||
diff --git a/systems/eldiron/websites/cloud/default.nix b/systems/eldiron/websites/cloud/default.nix index e1df883..c859f32 100644 --- a/systems/eldiron/websites/cloud/default.nix +++ b/systems/eldiron/websites/cloud/default.nix | |||
@@ -9,6 +9,15 @@ in { | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | config = lib.mkIf cfg.enable { | 11 | config = lib.mkIf cfg.enable { |
12 | services.borgBackup.profiles.global.includedPaths = [ | ||
13 | "nextcloud/appdata_occ80acffb591" | ||
14 | "nextcloud/files_external" | ||
15 | "nextcloud/config" | ||
16 | #"nextcloud/gpxpod" | ||
17 | "nextcloud/.ocdata" | ||
18 | "nextcloud/.htaccess" | ||
19 | "nextcloud/index.html" | ||
20 | ]; | ||
12 | myServices.dns.zones."immae.eu".subdomains.cloud = | 21 | myServices.dns.zones."immae.eu".subdomains.cloud = |
13 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | 22 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; |
14 | 23 | ||
diff --git a/systems/eldiron/websites/commento/default.nix b/systems/eldiron/websites/commento/default.nix index c5131b8..9abc180 100644 --- a/systems/eldiron/websites/commento/default.nix +++ b/systems/eldiron/websites/commento/default.nix | |||
@@ -12,6 +12,9 @@ in | |||
12 | enable = lib.mkEnableOption "Enable commento website"; | 12 | enable = lib.mkEnableOption "Enable commento website"; |
13 | }; | 13 | }; |
14 | config = lib.mkIf cfg.enable { | 14 | config = lib.mkIf cfg.enable { |
15 | services.borgBackup.profiles.global.includedPaths = [ | ||
16 | "vhost/tools.immae.eu/commento" | ||
17 | ]; | ||
15 | myServices.dns.zones."immae.eu".subdomains.commento = | 18 | myServices.dns.zones."immae.eu".subdomains.commento = |
16 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | 19 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; |
17 | 20 | ||
diff --git a/systems/eldiron/websites/cryptpad/default.nix b/systems/eldiron/websites/cryptpad/default.nix index 4635548..34a51cd 100644 --- a/systems/eldiron/websites/cryptpad/default.nix +++ b/systems/eldiron/websites/cryptpad/default.nix | |||
@@ -75,6 +75,9 @@ in | |||
75 | inherit domain port; | 75 | inherit domain port; |
76 | config = configFile; | 76 | config = configFile; |
77 | }; | 77 | }; |
78 | services.borgBackup.profiles.global.includedPaths = [ | ||
79 | "cryptpad/immaeEu" | ||
80 | ]; | ||
78 | services.websites.env.tools.modules = [ "proxy_wstunnel" ]; | 81 | services.websites.env.tools.modules = [ "proxy_wstunnel" ]; |
79 | security.acme.certs.eldiron.extraDomainNames = [ domain ]; | 82 | security.acme.certs.eldiron.extraDomainNames = [ domain ]; |
80 | services.websites.env.tools.vhostConfs.cryptpad = { | 83 | services.websites.env.tools.vhostConfs.cryptpad = { |
diff --git a/systems/eldiron/websites/tools/default.nix b/systems/eldiron/websites/tools/default.nix index b591190..46e6a9f 100644 --- a/systems/eldiron/websites/tools/default.nix +++ b/systems/eldiron/websites/tools/default.nix | |||
@@ -110,6 +110,21 @@ in { | |||
110 | ]; | 110 | ]; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | services.borgBackup.profiles.global.ignoredPaths = [ | ||
114 | "duply" | ||
115 | "kanboard" | ||
116 | "ntfy" | ||
117 | ]; | ||
118 | services.borgBackup.profiles.global.includedPaths = [ | ||
119 | "paste" | ||
120 | "dokuwiki/conf" | ||
121 | "dokuwiki/data" | ||
122 | "phpbb" | ||
123 | "shaarli/cache" | ||
124 | "shaarli/pagecache" | ||
125 | "shaarli/tmp" | ||
126 | ]; | ||
127 | |||
113 | myServices.chatonsProperties.services = { | 128 | myServices.chatonsProperties.services = { |
114 | adminer = adminer.chatonsProperties; | 129 | adminer = adminer.chatonsProperties; |
115 | dokuwiki = dokuwiki.chatonsProperties; | 130 | dokuwiki = dokuwiki.chatonsProperties; |