restic
This commit is contained in:
@@ -1,32 +1,243 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
name = "restic";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
inherit (lib.${namespace})
|
||||
mkOpt
|
||||
mkBoolOpt
|
||||
;
|
||||
|
||||
resticConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
serviceName = "${name}-rest-server";
|
||||
description = "restic";
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
# Configure the standard NixOS restic server service
|
||||
services.restic.server = {
|
||||
enable = true;
|
||||
dataDir = "${cfg.dataDir}/backup/restic";
|
||||
prometheus = true;
|
||||
listenAddress = "${cfg.listenAddress}:${toString cfg.port}";
|
||||
htpasswd-file = "${cfg.dataDir}/backup/restic/.htpasswd";
|
||||
extraFlags = [ "--no-auth" ];
|
||||
cfg = config.${namespace}.services.restic;
|
||||
|
||||
# Only process jobs that have enable = true.
|
||||
enabledBackups = filterAttrs (_name: jobCfg: jobCfg.enable) cfg.backups;
|
||||
enabledJobNames = attrNames enabledBackups;
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ntfy notify script
|
||||
# Reads NTFY_USER and NTFY_PASSWORD from the environment (injected via the
|
||||
# restic-ntfy.env SOPS template at runtime).
|
||||
#
|
||||
# On success, queries `restic snapshots --json` to retrieve stats from the
|
||||
# most recent snapshot and builds a rich summary message.
|
||||
# ---------------------------------------------------------------------------
|
||||
mkNotifyScript =
|
||||
jobName:
|
||||
pkgs.writeShellScript "restic-notify-${jobName}" ''
|
||||
STATUS="$1" # "success" or "failure"
|
||||
HOST="$(${pkgs.hostname}/bin/hostname)"
|
||||
TOPIC="${cfg.ntfy.topic}"
|
||||
SERVER="${cfg.ntfy.server}"
|
||||
|
||||
if [ "$STATUS" = "success" ]; then
|
||||
TITLE="Backup succeeded: ${jobName} on $HOST"
|
||||
PRIORITY="low"
|
||||
TAGS="white_check_mark,floppy_disk"
|
||||
|
||||
# Query the latest snapshot for metadata. RESTIC_* env vars are
|
||||
# already set by the restic systemd service so we can call restic
|
||||
# directly. Fall back gracefully if the query fails.
|
||||
SNAP_JSON="$(${pkgs.restic}/bin/restic snapshots --json --last 2>/dev/null || echo '[]')"
|
||||
|
||||
SNAP_ID="$( echo "$SNAP_JSON" | ${pkgs.jq}/bin/jq -r 'last | .short_id // "unknown"')"
|
||||
SNAP_TIME="$( echo "$SNAP_JSON" | ${pkgs.jq}/bin/jq -r 'last | .time[:19] // "unknown"' | ${pkgs.gnused}/bin/sed 's/T/ /')"
|
||||
SNAP_HOST="$( echo "$SNAP_JSON" | ${pkgs.jq}/bin/jq -r 'last | .hostname // "unknown"')"
|
||||
SNAP_PATHS="$(echo "$SNAP_JSON" | ${pkgs.jq}/bin/jq -r 'last | .paths[] // "unknown"' | ${pkgs.coreutils}/bin/tr '\n' ' ')"
|
||||
|
||||
MESSAGE="$(printf 'Job: %s\nHost: %s\nPaths: %s\nSnapshot: %s\nTime: %s' \
|
||||
'${jobName}' "$SNAP_HOST" "$SNAP_PATHS" "$SNAP_ID" "$SNAP_TIME")"
|
||||
else
|
||||
TITLE="Backup FAILED: ${jobName} on $HOST"
|
||||
PRIORITY="high"
|
||||
TAGS="rotating_light,floppy_disk"
|
||||
MESSAGE="Restic backup '${jobName}' failed. Check: journalctl -u restic-backups-${jobName}.service"
|
||||
fi
|
||||
|
||||
${pkgs.curl}/bin/curl -sf \
|
||||
--user "$NTFY_USER:$NTFY_PASSWORD" \
|
||||
-H "Title: $TITLE" \
|
||||
-H "Priority: $PRIORITY" \
|
||||
-H "Tags: $TAGS" \
|
||||
-d "$MESSAGE" \
|
||||
"$SERVER/$TOPIC" || true
|
||||
'';
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Failure-notify companion unit (triggered via OnFailure=)
|
||||
# ---------------------------------------------------------------------------
|
||||
mkFailureNotifyUnit =
|
||||
jobName:
|
||||
let
|
||||
notifyScript = mkNotifyScript jobName;
|
||||
in
|
||||
{
|
||||
description = "Notify ntfy on restic backup failure: ${jobName}";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${notifyScript} failure";
|
||||
EnvironmentFile = [ config.sops.templates."restic-ntfy.env".path ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
imports = [ resticConfig ];
|
||||
options.${namespace}.services.restic = {
|
||||
enable = mkBoolOpt false "Enable restic backup jobs";
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# ntfy notification options
|
||||
# -----------------------------------------------------------------------
|
||||
ntfy = {
|
||||
enable = mkBoolOpt false "Send ntfy notifications on backup success/failure";
|
||||
|
||||
server = mkOpt types.str "https://ntfy.mjallen.dev" "ntfy server base URL";
|
||||
|
||||
topic = mkOpt types.str "backups" "ntfy topic to publish notifications to";
|
||||
|
||||
userSecret =
|
||||
mkOpt types.str ""
|
||||
"SOPS secret key path for the ntfy username (must be declared in sops.secrets by the caller)";
|
||||
|
||||
passwordSecret =
|
||||
mkOpt types.str ""
|
||||
"SOPS secret key path for the ntfy password (must be declared in sops.secrets by the caller)";
|
||||
};
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Default excludes applied to every job (merged with per-job excludes)
|
||||
# -----------------------------------------------------------------------
|
||||
defaultExcludes = mkOpt (types.listOf types.str) [ ] "Exclude patterns applied to every backup job";
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Backup job definitions
|
||||
# -----------------------------------------------------------------------
|
||||
backups = mkOpt (types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
enable = mkBoolOpt true "Enable this backup job";
|
||||
|
||||
paths = mkOpt (types.listOf types.str) [ ] "Paths to back up";
|
||||
|
||||
exclude = mkOpt (types.listOf types.str) [ ] "Additional exclude patterns for this job";
|
||||
|
||||
# Repository — exactly one of repository / repositoryFile must be set.
|
||||
repository = mkOpt (types.nullOr types.str) null "Restic repository URL (plain string)";
|
||||
|
||||
repositoryFile =
|
||||
mkOpt (types.nullOr types.str) null
|
||||
"Path to a file containing the repository URL (e.g. from SOPS)";
|
||||
|
||||
passwordFile = mkOpt (types.nullOr types.str) null "Path to the restic repository password file";
|
||||
|
||||
environmentFile =
|
||||
mkOpt (types.nullOr types.str) null
|
||||
"Path to an environment file (e.g. REST credentials from a SOPS template)";
|
||||
|
||||
rcloneConfigFile =
|
||||
mkOpt (types.nullOr types.str) null
|
||||
"Path to an rclone config file (for rclone: repositories)";
|
||||
|
||||
# Timer
|
||||
timerConfig = mkOpt (types.attrsOf types.anything) {
|
||||
OnCalendar = "02:00";
|
||||
RandomizedDelaySec = "1h";
|
||||
Persistent = true;
|
||||
} "systemd timer configuration for this job";
|
||||
|
||||
# Pruning / retention
|
||||
pruneOpts = mkOpt (types.listOf types.str) [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 12"
|
||||
"--keep-yearly 2"
|
||||
] "restic forget flags that control snapshot retention";
|
||||
|
||||
# Misc
|
||||
initialize = mkBoolOpt true "Initialise the repository if it does not exist";
|
||||
createWrapper = mkBoolOpt true "Create a restic wrapper script for this job";
|
||||
inhibitsSleep = mkBoolOpt true "Inhibit system sleep while this backup is running";
|
||||
|
||||
extraBackupArgs = mkOpt (types.listOf types.str) [ ] "Extra arguments passed to restic backup";
|
||||
};
|
||||
}
|
||||
)) { } "Restic backup job definitions";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# -----------------------------------------------------------------------
|
||||
# CLI tools
|
||||
# -----------------------------------------------------------------------
|
||||
environment.systemPackages = with pkgs; [
|
||||
restic
|
||||
restic-integrity
|
||||
];
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# SOPS: ntfy credentials env-file template
|
||||
#
|
||||
# The secrets themselves (desktop/ntfy/user, desktop/ntfy/password) are
|
||||
# declared in the per-system sops.nix so they can carry the correct
|
||||
# sopsFile path. This module only renders the template that combines them.
|
||||
# -----------------------------------------------------------------------
|
||||
sops.templates."restic-ntfy.env" =
|
||||
mkIf (cfg.ntfy.enable && cfg.ntfy.userSecret != "" && cfg.ntfy.passwordSecret != "")
|
||||
{
|
||||
mode = "0600";
|
||||
content = ''
|
||||
NTFY_USER=${config.sops.placeholder.${cfg.ntfy.userSecret}}
|
||||
NTFY_PASSWORD=${config.sops.placeholder.${cfg.ntfy.passwordSecret}}
|
||||
'';
|
||||
restartUnits = map (name: "restic-backups-${name}.service") enabledJobNames;
|
||||
};
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Restic backup jobs
|
||||
# -----------------------------------------------------------------------
|
||||
services.restic.backups = mapAttrs (
|
||||
_name: jobCfg:
|
||||
{
|
||||
initialize = jobCfg.initialize;
|
||||
createWrapper = jobCfg.createWrapper;
|
||||
inhibitsSleep = jobCfg.inhibitsSleep;
|
||||
paths = jobCfg.paths;
|
||||
exclude = jobCfg.exclude ++ cfg.defaultExcludes;
|
||||
timerConfig = jobCfg.timerConfig;
|
||||
pruneOpts = jobCfg.pruneOpts;
|
||||
extraBackupArgs = jobCfg.extraBackupArgs;
|
||||
}
|
||||
// optionalAttrs (jobCfg.passwordFile != null) { inherit (jobCfg) passwordFile; }
|
||||
// optionalAttrs (jobCfg.repository != null) { inherit (jobCfg) repository; }
|
||||
// optionalAttrs (jobCfg.repositoryFile != null) { inherit (jobCfg) repositoryFile; }
|
||||
// optionalAttrs (jobCfg.environmentFile != null) { inherit (jobCfg) environmentFile; }
|
||||
// optionalAttrs (jobCfg.rcloneConfigFile != null) { inherit (jobCfg) rcloneConfigFile; }
|
||||
) enabledBackups;
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Systemd service overrides: ntfy env-file injection + notifications
|
||||
# -----------------------------------------------------------------------
|
||||
systemd.services = mkIf cfg.ntfy.enable (
|
||||
mkMerge (
|
||||
map (jobName: {
|
||||
# Inject the ntfy credentials env-file into the NixOS-generated
|
||||
# restic service and wire up the failure-notify companion unit.
|
||||
"restic-backups-${jobName}" = {
|
||||
serviceConfig = {
|
||||
EnvironmentFile = [ config.sops.templates."restic-ntfy.env".path ];
|
||||
# Send a success notification after the backup (and prune) completes.
|
||||
ExecStartPost = "${mkNotifyScript jobName} success";
|
||||
};
|
||||
unitConfig.OnFailure = "restic-notify-failure-${jobName}.service";
|
||||
};
|
||||
|
||||
# One-shot unit that fires on failure via OnFailure=.
|
||||
"restic-notify-failure-${jobName}" = mkFailureNotifyUnit jobName;
|
||||
}) enabledJobNames
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ desktop:
|
||||
user: ENC[AES256_GCM,data:IoDWBPg=,iv:Am5YWSr6qhQZumY/BUUgtL131q/gsk3OpSLFjPpYu8c=,tag:3fhkAZdukXbppH9BLUVSfA==,type:str]
|
||||
password: ENC[AES256_GCM,data:D0u9Wq67jDetyzI=,iv:yjL3Ywfa5VlKbMhQFduujReElGWTJFT2ppUEtYxsLwk=,tag:YlnW17CTmADN8p9rzwGhlQ==,type:str]
|
||||
repo: ENC[AES256_GCM,data:iWw+aBd1S1WVyP5QinxZBuw5JPvpgLi2uAeAf3AWpKccRtQfE2D8nOUE5ynIek1pkfBn,iv:ltqNrRXeDkiesc2Q6ScNcMGYTyQAYUonAqOfA9KRQTI=,tag:n7Z9iLgUCGUs7uJLLilLEg==,type:str]
|
||||
ntfy:
|
||||
user: ENC[AES256_GCM,data:cM7KklfgUQ==,iv:cmrJDVLlw5se/p2LqpYCSajtq+3qFKxZkSLKmfju0QI=,tag:rWVjjWUEdHyhKYamszaLPQ==,type:str]
|
||||
password: ENC[AES256_GCM,data:CYmfWQOzvmlTKsk=,iv:DiSHqpL8C6N1uTkYcttzXyawvq/psDJe3WkjhZ2hj/k=,tag:zaATIj3oaqPBlMzDxD+jdA==,type:str]
|
||||
system-ed25519-pub: ENC[AES256_GCM,data:yM0Q6bf5qoY02jxayk0F3U1d4mR5ZTAmGEscmYMIQncUthefbfhaBgZn2uaDwEdagSN6ihZ9IzZ8i+KEiCW8X1iWt+N2zd3dCyQCM9D/5VUDulvjoNE2IN+T/bIsbCfh,iv:iLuNOQV0M40wao1LBjwy0opqxZZRmPsAxTbg18CHn/Y=,tag:PmxE9ldU/hWEqKL4juLdBw==,type:str]
|
||||
system-ed25519-priv: ENC[AES256_GCM,data:neR7rxQic+JxfkupQh9hIFOSF+QEahIWhFaP4Vk7bDBims9nimy1WRF4jwwoY8+rco+mfrQZT+/F5URpC0uCf0UeL+RCnGcVPMS+NS1+T9/Wygh1ZfsdQNv3G9+H2r59n4kGmaPfaLxfeftNf2M2YkTD5VEt4oZuHg8gcivoeQ8evtezjicIZGLrMxJLXn+SxDq6+glKKk4xOel9AdYsXTw6fCZ/y8uXCjhpMp0FvV6DZbeBawm8O+R/m0KUIEBpfDLXWXnpjZ71XhYCNYRyIwiDBhW5S0o0X+0iX4vSQfxBcwd1oLPYWJjYlMcUSTmaiKH2x5JaQJRiXCd6t3vQchRNQ81wNbL1Q/xERO8RsUMu7u0EW5qeBiGAuW7z/sx3yV8c8SNBwr1GfT+d3g77EShXn48XaGIYvNKW1ANdxkgSc6h66acWeI1kY6/Dk9IpVxvuAQgV3Ukwv8HDCnSHsKJVfm7KYw/jqVZGKTE/msVkCm7KGig1OfinZCs5VvBO7YSWrSyeb580kiiKf32xxBJtmELWueVVov1c,iv:m2Eqw9OAWf1UO38r5i4DVdh9zqLdrbggUOcxqu2339w=,tag:+yq0MDE3dofu8XbDdcTbPQ==,type:str]
|
||||
system-rsa-pub: ENC[AES256_GCM,data:uqiKfnAPDXEo0UF0kITdSaGeYaG5Je8jLx2S0tYEyz2jGlTYGvervjQvpbSogHot0A2qgJUc+E2o161fJFNDH599MnI7n3WGJpNQekfUZh/kGM3tBOigzMl6d0UdDjWnJh7IQo06dD35rCE79ZLg5HQEuJz602HG36Be/XfJ2nWAVDqd+/F8+06jrc7RKvecp4ubbrrz9u/wj9BZRLN3GcG8QV4MCRY5neX7MrLWNtB9wcuRS/kt7jLtM2aIDd7a+DZvcUM+4fbWLqpwMQq4N/pf6AYLs/GuemjaZ4iE8evBvHoP82TaCLUhd4jgWp0g8KamK+DHwZAn2nkNGVNOFTSy4p3hA2tkugDIubDhY4ahKAbf9Z0IgY+2iW/ICtvSGxcjT7zIgynnOHTZn0wdVUJEWomTwWdmjCdWo5WSQnCvSEXngNDvEhDVkyA51nBaKVKnshHwOEFiV/0RvO+WnjRjR1jnPz4sksp58OzChd5J4YrA8Y2RbhHFxFV/W3Sn9HFUbGUWo2xHWqhWTBhVmmJSHlwkuG1hzZi1q18aHLgaJBbJzlaDcWLrn8XMm7CPMQzf4+iMJliaANHwGKv52+NEyRMcsgAHUyfsW2qU2uZtCkziPMzxQpJZrNibZrAdwII50hT2B4BQBPVzK1VBC+BLrYmRl+Qvie9C5yzzllQMhLEcA0ChI5+MJ6Rul8UjVpBxsWteLWkc4KHkOabjDLGbF6UAjpnj8xpGCZteLfno6UxJFavXaqm2IsX1IgW80ptPKuJmxiwnkQg7yue19/lsB9/5pWfgHfpThj7Rt25TUIAdl0VtC0yer7UuIKdyl6t58TZHZ78ncTWWRqgnEPABjsN3oUpuhCUbtaq0u1jbJt6CUfIXhaO9Y/YlMPwMyfacAZKQBlg2BxBbtycsWG/ktMUKAbNIdxr+g2kKCEGBgpuMJXmhsE4QmLzZJ1J+y9TOkBrimpJPY+awYkAL0q86HVQ=,iv:tD8LK0+Ksb+3Ahhx2td//ktIgeyFykdrFjN1HURZwno=,tag:XeRgt9DQhWUynhBRZF+rcA==,type:str]
|
||||
@@ -161,8 +164,8 @@ sops:
|
||||
STU1bkRXNVRsYkJac0RPOVpZTmJCaW8KS9zUt1QpP0k38LQ6OMCkL7Ee3r/fZsWp
|
||||
hfISSv9uO1uEmgRHtXSRaElQmOmGgcZB7oqSJvY3SJHxENPiCK4cDw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-03-23T21:04:05Z"
|
||||
mac: ENC[AES256_GCM,data:RzOE3TI/cz2OD/cfyuR4aUTm2idclRiBEMzex8HAdg9MiHbxrBST7UF1D0hkG8tRxJZccKerwjJLj+cY+zfMGI59299AC8PEdHQFnyK8JJH3Nk93Bl5Ctsd0eSRV5UHo+XerZbEh0/5o2YlXLQcar++08GhDf0bRjiacjBt6TRc=,iv:79JFaUW4ro35VS9NFlSdG57y6NJ10KglRQOLfhiiQHY=,tag:7CpnuBT5kdcMqEsKcGtimA==,type:str]
|
||||
lastmodified: "2026-03-24T18:20:10Z"
|
||||
mac: ENC[AES256_GCM,data:X+n7XWuSM7fKBwimjhavlb4ZBHqS2C5U01HchnQ2WNJDCqg4rebCP08Fvv2WZOCUexS+Xp1W3C43vHmC51SMPB/8R/mABPDviC5B4HjGjp+WEET1jcoZtO7EZ5zCJwxAuIC4U5JrZQA89Uq64urJ1ggKhlt4Vv6cYpq3WYBNQ6s=,iv:GM4uRui5PjYH30zwani5uA5EYQbI5frUVXwsYk5Acoc=,tag:myVURZ7H7328/UrDnV/naA==,type:str]
|
||||
pgp:
|
||||
- created_at: "2026-02-06T15:34:29Z"
|
||||
enc: |-
|
||||
@@ -185,4 +188,4 @@ sops:
|
||||
-----END PGP MESSAGE-----
|
||||
fp: CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.11.0
|
||||
version: 3.12.1
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
restic
|
||||
# restic-browser
|
||||
restic-integrity
|
||||
];
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
{
|
||||
${namespace}.services.restic = {
|
||||
enable = true;
|
||||
|
||||
services.restic.backups = {
|
||||
jallen-nas = {
|
||||
initialize = true;
|
||||
createWrapper = true;
|
||||
inhibitsSleep = true;
|
||||
environmentFile = config.sops.templates."restic.env".path;
|
||||
passwordFile = config.sops.secrets."desktop/restic/password".path;
|
||||
repositoryFile = config.sops.secrets."desktop/restic/repo".path;
|
||||
paths = [
|
||||
"/home/matt"
|
||||
];
|
||||
exclude = [
|
||||
"/home/matt/Steam"
|
||||
"/home/matt/Heroic"
|
||||
"/home/matt/1TB"
|
||||
"/home/matt/Downloads"
|
||||
"/home/matt/Nextcloud"
|
||||
"/home/matt/.cache"
|
||||
"/home/matt/.local/share/Steam"
|
||||
"/home/matt/.var/app/com.valvesoftware.Steam"
|
||||
"/home/matt/.tmp"
|
||||
"/home/matt/.thumbnails"
|
||||
"/home/matt/.compose-cache"
|
||||
];
|
||||
# -------------------------------------------------------------------------
|
||||
# ntfy notifications
|
||||
# -------------------------------------------------------------------------
|
||||
ntfy = {
|
||||
enable = true;
|
||||
server = "https://ntfy.mjallen.dev";
|
||||
topic = "backups";
|
||||
# SOPS secret keys — these must be declared in sops.nix with the correct
|
||||
# sopsFile so that sops-nix knows how to decrypt them.
|
||||
userSecret = "desktop/ntfy/user";
|
||||
passwordSecret = "desktop/ntfy/password";
|
||||
};
|
||||
proton-drive = {
|
||||
initialize = true;
|
||||
createWrapper = true;
|
||||
inhibitsSleep = true;
|
||||
passwordFile = config.sops.secrets."desktop/restic/password".path;
|
||||
rcloneConfigFile = "/home/matt/.config/rclone/rclone.conf";
|
||||
repository = "rclone:proton-drive:backup-nix";
|
||||
paths = [
|
||||
"/home/matt"
|
||||
];
|
||||
exclude = [
|
||||
"/home/matt/Steam"
|
||||
"/home/matt/Heroic"
|
||||
"/home/matt/1TB"
|
||||
"/home/matt/Downloads"
|
||||
"/home/matt/Nextcloud"
|
||||
"/home/matt/.cache"
|
||||
"/home/matt/.local/share/Steam"
|
||||
"/home/matt/.var/app/com.valvesoftware.Steam"
|
||||
"/home/matt/.tmp"
|
||||
"/home/matt/.thumbnails"
|
||||
"/home/matt/.compose-cache"
|
||||
];
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Excludes shared by every job on this host
|
||||
# -------------------------------------------------------------------------
|
||||
defaultExcludes = [
|
||||
"/home/matt/Steam"
|
||||
"/home/matt/Heroic"
|
||||
"/home/matt/1TB"
|
||||
"/home/matt/Downloads"
|
||||
"/home/matt/Nextcloud"
|
||||
"/home/matt/.cache"
|
||||
"/home/matt/.local/share/Steam"
|
||||
"/home/matt/.var/app/com.valvesoftware.Steam"
|
||||
"/home/matt/.tmp"
|
||||
"/home/matt/.thumbnails"
|
||||
"/home/matt/.compose-cache"
|
||||
];
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Backup jobs
|
||||
# -------------------------------------------------------------------------
|
||||
backups = {
|
||||
jallen-nas = {
|
||||
paths = [ "/home/matt" ];
|
||||
environmentFile = config.sops.templates."restic.env".path;
|
||||
passwordFile = config.sops.secrets."desktop/restic/password".path;
|
||||
repositoryFile = config.sops.secrets."desktop/restic/repo".path;
|
||||
};
|
||||
|
||||
proton-drive = {
|
||||
paths = [ "/home/matt" ];
|
||||
passwordFile = config.sops.secrets."desktop/restic/password".path;
|
||||
rcloneConfigFile = "/home/matt/.config/rclone/rclone.conf";
|
||||
repository = "rclone:proton-drive:backup-nix";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,6 +51,14 @@ in
|
||||
sopsFile = desktopSopsFile;
|
||||
mode = "0600";
|
||||
};
|
||||
"desktop/ntfy/user" = {
|
||||
sopsFile = desktopSopsFile;
|
||||
mode = "0600";
|
||||
};
|
||||
"desktop/ntfy/password" = {
|
||||
sopsFile = desktopSopsFile;
|
||||
mode = "0600";
|
||||
};
|
||||
# ------------------------------
|
||||
# SSH keys
|
||||
# ------------------------------
|
||||
|
||||
Reference in New Issue
Block a user