Backing up user files to Google Drive #
Using a combination of Rclone and Restic we can create scheduled, deduplicated backups of user files. This requires a a valid client ID, client secret and access token set up through the google developer console.
Configuring Rclone #
Rclone can be set up using a sops-nix template as such:
{
inputs,
...
}:
{
flake.modules.homeManager.rclone =
{
pkgs,
lib,
config,
...
}:
{
options = {
rclone.enable = lib.mkEnableOption "rclone google drive remote";
secrets.rclone.enable = lib.mkEnableOption "rclone google drive secrets";
};
config = lib.mkMerge [
(lib.mkIf config.rclone.enable {
programs.rclone.enable = true;
})
(lib.mkIf (config.rclone.enable && config.secrets.enable && config.secrets.rclone.enable) {
sops = {
secrets = {
"restic/repository" = { };
"restic/password" = { };
"rclone/client_id" = { };
"rclone/client_secret" = { };
"rclone/access_token" = { };
};
templates."rclone.conf".content = ''
[gdrive]
scope = drive.file
type = drive
client_id = ${config.sops.placeholder."rclone/client_id"}
client_secret = ${config.sops.placeholder."rclone/client_secret"}
token = ${config.sops.placeholder."rclone/access_token"}
'';
};
home.activation."rclone.conf" = ''
mkdir -p ~/.config/rclone
ln -sf ${config.sops.templates."rclone.conf".path} ~/.config/rclone/rclone.conf
'';
})
];
};
}Configuring Restic #
Restic can be configured using the services.restic config option as follows:
{
inputs,
...
}:
{
flake.modules.homeManager.restic =
{
pkgs,
lib,
config,
...
}:
{
options = {
restic.enable = lib.mkEnableOption "restic backups";
secrets.restic.enable = lib.mkEnableOption "restic repository secrets";
};
config = lib.mkMerge [
(lib.mkIf config.restic.enable {
home.packages = with pkgs; [
restic
restic-browser
];
})
(lib.mkIf (config.restic.enable && config.secrets.enable && config.secrets.restic.enable) {
sops.secrets = {
"restic/repository" = { };
"restic/password" = { };
};
services.restic = {
enable = true;
backups.daily = {
repositoryFile = config.sops.secrets."restic/repository".path;
passwordFile = config.sops.secrets."restic/password".path;
paths = [
"${config.home.homeDirectory}/Documents"
"${config.home.homeDirectory}/Pictures"
"${config.home.homeDirectory}/Books"
];
pruneOpts = [
"--keep-daily 3"
"--keep-weekly 7"
"--keep-monthly 15"
"--keep-yearly 30"
];
timerConfig = {
OnCalendar = "00:00";
RandomizedDelaySec = "45m";
Persistent = true;
};
};
};
})
];
};
}