litestream backups for nextcloud

This commit is contained in:
Noah Masur 2022-10-08 15:52:05 +00:00
parent e89db82e7f
commit 8dba2ef88b
3 changed files with 98 additions and 12 deletions

View File

@ -26,6 +26,13 @@ nixpkgs.lib.nixosSystem {
publicKey = publicKey =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s"; "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s";
# Backup config
backupS3 = {
endpoint = "s3.us-west-002.backblazeb2.com";
bucket = "noahmasur-backup";
accessKeyId = "0026b0e73b2e2c80000000004";
};
# Grant access to Jellyfin directories from nextcloud # Grant access to Jellyfin directories from nextcloud
users.users.nextcloud.extraGroups = [ "jellyfin" ]; users.users.nextcloud.extraGroups = [ "jellyfin" ];
} }

View File

@ -1,6 +1,8 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let adminpassFile = "/var/lib/nextcloud/creds"; let
adminpassFile = "/var/lib/nextcloud/creds";
backupS3File = "/var/lib/nextcloud/backup-creds";
in { in {
@ -13,6 +15,22 @@ in {
description = "Hostname for Nextcloud"; description = "Hostname for Nextcloud";
}; };
# Options for backup
backupS3 = {
endpoint = lib.mkOption {
type = lib.types.str;
description = "S3 endpoint for backups";
};
bucket = lib.mkOption {
type = lib.types.str;
description = "S3 bucket for backups";
};
accessKeyId = lib.mkOption {
type = lib.types.str;
description = "S3 access key ID for backups";
};
};
}; };
config = { config = {
@ -72,18 +90,73 @@ in {
}]; }];
}]; }];
# Create credentials files # Create credentials file for nextcloud
system.activationScripts.nextcloud = { systemd.services.nextcloud-creds = {
deps = [ "age" ]; requiredBy = [ "nextcloud-setup.service" ];
text = '' before = [ "nextcloud-setup.service" ];
if [ ! -f "${adminpassFile}" ]; then serviceConfig = {
$DRY_RUN_CMD mkdir --parents $VERBOSE_ARG $(dirname ${adminpassFile}) Type = "oneshot";
$DRY_RUN_CMD ${pkgs.age}/bin/age --decrypt \ User = "root";
};
script = ''
mkdir --parents $(dirname ${adminpassFile})
${pkgs.age}/bin/age --decrypt \
--identity ${config.identityFile} \
--output ${adminpassFile} \
${builtins.toString ../../private/nextcloud.age}
chown nextcloud:nextcloud ${adminpassFile}
chmod 0700 ${adminpassFile}
'';
};
## Backup config
# Open to groups, allowing for backups
systemd.services.phpfpm-nextcloud.serviceConfig.StateDirectoryMode =
lib.mkForce "0770";
# Allow litestream and nextcloud to share a sqlite database
users.users.litestream.extraGroups = [ "nextcloud" ];
users.users.nextcloud.extraGroups = [ "litestream" ];
# Backup sqlite database with litestream
services.litestream = {
enable = true;
settings = {
dbs = [{
path = "/var/lib/nextcloud/data/nextcloud.db";
replicas = [{
url =
"s3://${config.backupS3.bucket}.${config.backupS3.endpoint}/nextcloud";
}];
}];
};
environmentFile = backupS3File;
};
# Don't start litestream unless nextcloud is up
systemd.services.litestream = {
after = [ "phpfpm-nextcloud.service" ];
requires = [ "phpfpm-nextcloud.service" ];
environment.LITESTREAM_ACCESS_KEY_ID = config.backupS3.accessKeyId;
};
# Create credentials file for litestream
systemd.services.litestream-s3 = {
requiredBy = [ "litestream.service" ];
before = [ "litestream.service" ];
serviceConfig = {
Type = "oneshot";
User = "root";
};
script = ''
echo \
LITESTREAM_SECRET_ACCESS_KEY=$(${pkgs.age}/bin/age --decrypt \
--identity ${config.identityFile} \ --identity ${config.identityFile} \
--output ${adminpassFile} \ ${builtins.toString ../../private/backup.age} \
${builtins.toString ../../private/nextcloud.age} ) > ${backupS3File}
$DRY_RUN_CMD chown nextcloud:nextcloud ${adminpassFile} chown litestream:litestream ${backupS3File}
fi chmod 0700 ${backupS3File}
''; '';
}; };

6
private/backup.age Normal file
View File

@ -0,0 +1,6 @@
age-encryption.org/v1
-> ssh-ed25519 MgHaOw 2y5C1sRq3NZqmfGBiPgMS7qcU5v+70wri5xkXbceaHM
zyd7b+OuVi3rxxUEm+QW/80M80SSKaebOwOioRjnYak
--- yZQxxjYYNouD5wnEj+qNjUSrRU01hXvWUuax4C252i8
¤à/<2F>2*®ŒM•ûD©ø^ÓœOßÆQ
5<¤áÝM18o»3´LÓœZiïùºò¹Ö7ð±9ÆTL<54>ø