feat: add backup for server
This commit is contained in:
parent
20ee47caa2
commit
f7409e0537
14 changed files with 256 additions and 165 deletions
|
|
@ -35,6 +35,12 @@ in
|
||||||
./sops-conf.nix # Secret
|
./sops-conf.nix # Secret
|
||||||
./nginx.nix
|
./nginx.nix
|
||||||
./mail.nix
|
./mail.nix
|
||||||
|
# (import ./netbird.nix {
|
||||||
|
# domain = "pre7780.dn";
|
||||||
|
# coturnPassFile = config.sops.secrets."netbird/coturn/password".path;
|
||||||
|
# idpSecret = config.sops.secrets."netbird/oidc/secret".path;
|
||||||
|
# dataStoreEncryptionKey = config.sops.secrets."netbird/dataStoreKey".path;
|
||||||
|
# })
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
|
|
||||||
../../modules/presets/basic.nix
|
../../modules/presets/basic.nix
|
||||||
|
|
@ -63,8 +69,8 @@ in
|
||||||
|
|
||||||
(import ../../modules/nextcloud.nix {
|
(import ../../modules/nextcloud.nix {
|
||||||
hostname = "nextcloud.pre7780.dn";
|
hostname = "nextcloud.pre7780.dn";
|
||||||
configureACME = false;
|
configureACME = true;
|
||||||
https = false;
|
https = true;
|
||||||
adminpassFile = config.sops.secrets."nextcloud/adminPassword".path;
|
adminpassFile = config.sops.secrets."nextcloud/adminPassword".path;
|
||||||
trusted = [ "nextcloud.daccc.info" ];
|
trusted = [ "nextcloud.daccc.info" ];
|
||||||
})
|
})
|
||||||
|
|
|
||||||
65
system/dev/dn-pre7780/netbird.nix
Normal file
65
system/dev/dn-pre7780/netbird.nix
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
domain,
|
||||||
|
idpSecret,
|
||||||
|
dataStoreEncryptionKey,
|
||||||
|
coturnPassFile,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
port = 51820;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.netbird = {
|
||||||
|
server = {
|
||||||
|
enable = true;
|
||||||
|
domain = "netbird.${domain}";
|
||||||
|
enableNginx = true;
|
||||||
|
management = {
|
||||||
|
oidcConfigEndpoint = "https://keycloak.net.dn/realms/master/.well-known/openid-configuration";
|
||||||
|
settings = {
|
||||||
|
DataStoreEncryptionKey = {
|
||||||
|
_secret = dataStoreEncryptionKey;
|
||||||
|
};
|
||||||
|
TURNConfig = {
|
||||||
|
Secret = {
|
||||||
|
_secret = idpSecret;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
IdpManagerConfig = {
|
||||||
|
ClientConfig = {
|
||||||
|
ClientID = "netbird-backend";
|
||||||
|
ClientSecret = {
|
||||||
|
_secret = idpSecret;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
coturn = {
|
||||||
|
user = "netbird";
|
||||||
|
passwordFile = coturnPassFile;
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
dashboard.settings = {
|
||||||
|
USE_AUTH0 = false;
|
||||||
|
AUTH_AUTHORITY = "https://keycloak.net.dn/realms/master";
|
||||||
|
AUTH_CLIENT_ID = "netbird";
|
||||||
|
AUTH_AUDIENCE = "netbird";
|
||||||
|
AUTH_SUPPORTED_SCOPES = "openid profile email offline_access api";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
clients.default = {
|
||||||
|
inherit port;
|
||||||
|
openFirewall = true;
|
||||||
|
name = "netbird";
|
||||||
|
interface = "wt0";
|
||||||
|
hardened = true;
|
||||||
|
dns-resolver.address = "10.0.0.1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."netbird.${domain}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
email = "danny@net.dn";
|
email = "danny@net.dn";
|
||||||
dnsProvider = "pdns";
|
dnsProvider = "pdns";
|
||||||
dnsPropagationCheck = false;
|
dnsPropagationCheck = false;
|
||||||
# environmentFile = config.sops.secrets."acme/pdns".path;
|
environmentFile = config.sops.secrets."acme/pdns".path;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ acme:
|
||||||
pdns: ENC[AES256_GCM,data:+InGSnaGIFVtDRlVltzWbZfquzodHUQrPeMRBnVNB9mrajlKr5dFK6DD8dXAvN7UjZFBfrgZefOPkmLR2ncLXGOV2Kl7jorVw50Y0f0iKl7mqwHaZKaQdk7cpGDkCrt/LvfbP9x7gVrs6pQpsU+c/P5rbBLRyejchh/WtiyzgowYIJxYohggeG09+l7YI3FR6U5wiymIRISpNBGEhwG0q17qdAhdtc49qP/K,iv:JcSlxAwHwU528S7iSpAnSbUZw7iO+LMjR3qGwRHp+Zk=,tag:twf2WOQb/yZ3GtN/hlikMA==,type:str]
|
pdns: ENC[AES256_GCM,data:+InGSnaGIFVtDRlVltzWbZfquzodHUQrPeMRBnVNB9mrajlKr5dFK6DD8dXAvN7UjZFBfrgZefOPkmLR2ncLXGOV2Kl7jorVw50Y0f0iKl7mqwHaZKaQdk7cpGDkCrt/LvfbP9x7gVrs6pQpsU+c/P5rbBLRyejchh/WtiyzgowYIJxYohggeG09+l7YI3FR6U5wiymIRISpNBGEhwG0q17qdAhdtc49qP/K,iv:JcSlxAwHwU528S7iSpAnSbUZw7iO+LMjR3qGwRHp+Zk=,tag:twf2WOQb/yZ3GtN/hlikMA==,type:str]
|
||||||
cloudflare:
|
cloudflare:
|
||||||
secret: ENC[AES256_GCM,data:tritGdt3bWm/YtfdF2kO8qIBisa2rGF9/Dpl8R79e6REe//YKZFqFg==,iv:UG53JZ55+gDCPJzKjbVaWnpgOdvqcRoDUg8ef9xOV9A=,tag:JD3s28dsA9G2fqtz4soATA==,type:str]
|
secret: ENC[AES256_GCM,data:tritGdt3bWm/YtfdF2kO8qIBisa2rGF9/Dpl8R79e6REe//YKZFqFg==,iv:UG53JZ55+gDCPJzKjbVaWnpgOdvqcRoDUg8ef9xOV9A=,tag:JD3s28dsA9G2fqtz4soATA==,type:str]
|
||||||
|
netbird:
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:hSVMUEBL0kCvRLD3zd57SLhNIAFOR4eaJPcIIIIUJng=,iv:VhfseftQNlXSDCWuaYQUIklMUCkUbChyWbJl3qgD75M=,tag:vbqov0VgA0XNZfzcr3FZgA==,type:str]
|
||||||
|
dataStoreKey: ENC[AES256_GCM,data:vV2wgo5qFS+DC1NmOjVddZW9HAsRMpUFH+t/70iQ3A5YXkhbWoCeSxZDyAg=,iv:tKqh28qj8gqHfcb44Ej731w6NKi29X4iEwIOQ4ZcCzA=,tag:ObAxVrUctm6pbmXSQw7j5w==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv
|
- recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv
|
||||||
|
|
@ -29,7 +33,7 @@ sops:
|
||||||
MEdmWkFwNXZoR1ZVRnQ0aWlkYzZwSmsK0EFecUIdqlDKX08oRCoDQQ3QCX1wzb8w
|
MEdmWkFwNXZoR1ZVRnQ0aWlkYzZwSmsK0EFecUIdqlDKX08oRCoDQQ3QCX1wzb8w
|
||||||
lghDJhWlfuKr+X24GoE4UK04aJVLqVMRRI4BJW+LQXeHS+dWKu3mQA==
|
lghDJhWlfuKr+X24GoE4UK04aJVLqVMRRI4BJW+LQXeHS+dWKu3mQA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-09-22T14:30:13Z"
|
lastmodified: "2025-09-26T14:45:30Z"
|
||||||
mac: ENC[AES256_GCM,data:Ak9QKKRWDFQk9GNkk2yiN+42DB/Gj7dXmiNOna0BKRwI7gkVl+ie4Iis6jhZ2aEe1vO8rgBurcSQd9xVyFOIJa16p7L1GD1doZWn0Gq3yerIwzjtaQMoS84e/cTTiWnj9shAe+Sm7vhk3ZJzJzbpYtBTspVE+iyZ+LafIE3XSCc=,iv:j53phA/h5cqWEiEviIjgbLxcPPOGWUq+UHFG1tCWkrw=,tag:Z5fnbnE2hfeHQ74Li3EVVw==,type:str]
|
mac: ENC[AES256_GCM,data:RAxzEJsfAY9UA15ln+uqEGoVli2oQEVP/8DrPEluQCfMYjMacbTlhIWfGXvUhFHZbY1/M0Q1IC/elY7iWqKn7Qc2VE+elTNHj+MTzp23pHUaHRo2h0kqcqnjdU1SeLNLJ5CDMp/wYyKKSeqde1UcQkhpE2sa5gnpVOd+JAJxCas=,iv:uD0qIHrI5uecUPGfOMvvcgr0NrbtTbHHxbdOX9dfDfw=,tag:FmnDi3opIobtIFI2rl+kWw==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.10.2
|
version: 3.10.2
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,41 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib) optionalAttrs;
|
inherit (lib) optionalAttrs mkIf hasAttr;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
sops = {
|
sops = {
|
||||||
secrets = {
|
secrets = {
|
||||||
"wireguard/conf" = { };
|
"wireguard/conf" = { };
|
||||||
"nextcloud/adminPassword" = lib.mkIf config.services.nextcloud.enable {
|
"nextcloud/adminPassword" = mkIf config.services.nextcloud.enable {
|
||||||
owner = "nextcloud";
|
owner = "nextcloud";
|
||||||
group = "nextcloud";
|
group = "nextcloud";
|
||||||
};
|
};
|
||||||
"openldap/adminPassword" = lib.mkIf config.services.openldap.enable {
|
"openldap/adminPassword" = mkIf config.services.openldap.enable {
|
||||||
owner = config.users.users.openldap.name;
|
owner = config.users.users.openldap.name;
|
||||||
group = config.users.users.openldap.group;
|
group = config.users.users.openldap.group;
|
||||||
mode = "0660";
|
mode = "0660";
|
||||||
};
|
};
|
||||||
"lam/env" = { };
|
"lam/env" = { };
|
||||||
"dovecot/openldap" = lib.mkIf (config.services.postfix.enable && config.services.openldap.enable) {
|
"dovecot/openldap" = mkIf (config.services.postfix.enable && config.services.openldap.enable) {
|
||||||
owner = config.services.dovecot2.user;
|
owner = config.services.dovecot2.user;
|
||||||
group = config.services.dovecot2.group;
|
group = config.services.dovecot2.group;
|
||||||
mode = "0660";
|
mode = "0660";
|
||||||
};
|
};
|
||||||
|
|
||||||
# "acme/pdns" = {
|
"netbird/oidc/secret" = mkIf config.services.netbird.server.dashboard.enable {
|
||||||
# mode = "0660";
|
owner = "netbird";
|
||||||
# owner = "acme";
|
};
|
||||||
# group = "acme";
|
|
||||||
# };
|
"netbird/coturn/password" = mkIf config.services.netbird.server.coturn.enable {
|
||||||
|
owner = "turnserver";
|
||||||
|
key = "netbird/oidc/secret";
|
||||||
|
};
|
||||||
|
"netbird/dataStoreKey" = mkIf config.services.netbird.server.management.enable {
|
||||||
|
owner = "netbird";
|
||||||
|
};
|
||||||
|
"acme/pdns" = mkIf (hasAttr "acme" config.users.users) {
|
||||||
|
owner = "acme";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// (optionalAttrs config.services.stalwart-mail.enable (
|
// (optionalAttrs config.services.stalwart-mail.enable (
|
||||||
let
|
let
|
||||||
|
|
|
||||||
92
system/dev/dn-server/backup.nix
Normal file
92
system/dev/dn-server/backup.nix
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf;
|
||||||
|
backupAt = "*-*-* 03:00:00";
|
||||||
|
backupPath = "/mnt/backup_dn";
|
||||||
|
backupScript = pkgs.writeShellScript "backup-nextcloud.sh" ''
|
||||||
|
nextcloudPath="${config.services.nextcloud.datadir}"
|
||||||
|
|
||||||
|
if [ ! -d "$nextcloudPath" ]; then
|
||||||
|
echo "nextcloud path not found: $nextcloudPath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
backupPath="${backupPath}"
|
||||||
|
nextcloudBakPath="$backupPath"
|
||||||
|
|
||||||
|
if [ ! -d "$backupPath" ]; then
|
||||||
|
echo "Backup device is not mounted: $backupPath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Start syncing..."
|
||||||
|
${pkgs.rsync}/bin/rsync -rh --delete "$nextcloudPath" "$nextcloudBakPath"
|
||||||
|
echo "Data dir backup completed."
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
fileSystems."/mnt/backup_dn" = {
|
||||||
|
device = "/dev/disk/by-uuid/FBD9-F625";
|
||||||
|
fsType = "exfat";
|
||||||
|
options = [
|
||||||
|
"x-systemd.automount"
|
||||||
|
"noauto"
|
||||||
|
"x-systemd.idle-timeout=600"
|
||||||
|
"nofail"
|
||||||
|
"user"
|
||||||
|
"x-gvfs-show"
|
||||||
|
"gid=1000"
|
||||||
|
"uid=1000"
|
||||||
|
"dmask=000"
|
||||||
|
"fmask=000"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# ==== Advance Backup ==== #
|
||||||
|
# services.pgbackrest = {
|
||||||
|
# enable = true;
|
||||||
|
# repos.localhost.path = "${backupPath}/postgresql";
|
||||||
|
# };
|
||||||
|
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
startAt = backupAt;
|
||||||
|
pgdumpOptions = "--no-owner";
|
||||||
|
databases = [
|
||||||
|
"nextcloud"
|
||||||
|
"vaultwarden"
|
||||||
|
"paperless"
|
||||||
|
];
|
||||||
|
location = "${backupPath}/postgresql";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = mkIf config.services.nextcloud.enable {
|
||||||
|
timers = {
|
||||||
|
"nextcloud-backup" = {
|
||||||
|
enable = true;
|
||||||
|
description = "Nextcloud backup";
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = backupAt;
|
||||||
|
Persistent = true;
|
||||||
|
OnUnitActiveSec = "1d";
|
||||||
|
AccuracySec = "1h";
|
||||||
|
Unit = "nextcloud-backup.service";
|
||||||
|
};
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services."nextcloud-backup" = {
|
||||||
|
enable = true;
|
||||||
|
serviceConfig = {
|
||||||
|
User = "nextcloud";
|
||||||
|
ExecStart = "${backupScript}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,23 +1,6 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
fileSystems."/mnt/backup_dn" = {
|
|
||||||
device = "/dev/disk/by-uuid/FBD9-F625";
|
|
||||||
fsType = "exfat";
|
|
||||||
options = [
|
|
||||||
"x-systemd.automount"
|
|
||||||
"noauto"
|
|
||||||
"x-systemd.idle-timeout=600"
|
|
||||||
"nofail"
|
|
||||||
"user"
|
|
||||||
"x-gvfs-show"
|
|
||||||
"gid=1000"
|
|
||||||
"uid=1000"
|
|
||||||
"dmask=000"
|
|
||||||
"fmask=000"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages;
|
boot.kernelPackages = pkgs.linuxPackages;
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ in
|
||||||
intel-bus-id = "PCI:0:2:0";
|
intel-bus-id = "PCI:0:2:0";
|
||||||
nvidia-bus-id = "PCI:1:0:0";
|
nvidia-bus-id = "PCI:1:0:0";
|
||||||
})
|
})
|
||||||
|
./backup.nix
|
||||||
./security.nix
|
./security.nix
|
||||||
./sops-conf.nix
|
./sops-conf.nix
|
||||||
./boot.nix
|
./boot.nix
|
||||||
|
|
@ -56,8 +57,6 @@ in
|
||||||
})
|
})
|
||||||
(import ../../modules/nextcloud.nix {
|
(import ../../modules/nextcloud.nix {
|
||||||
hostname = "nextcloud.net.dn";
|
hostname = "nextcloud.net.dn";
|
||||||
dataBackupPath = "/mnt/backup_dn";
|
|
||||||
dbBackupPath = "/mnt/backup_dn";
|
|
||||||
adminpassFile = config.sops.secrets."nextcloud/adminPassword".path;
|
adminpassFile = config.sops.secrets."nextcloud/adminPassword".path;
|
||||||
trusted = [ "nextcloud.daccc.info" ];
|
trusted = [ "nextcloud.daccc.info" ];
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,7 @@ in
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
oci-containers = {
|
oci-containers = {
|
||||||
backend = "docker";
|
backend = "podman";
|
||||||
containers = {
|
containers = {
|
||||||
uptime-kuma = {
|
uptime-kuma = {
|
||||||
extraOptions = [ "--network=host" ];
|
extraOptions = [ "--network=host" ];
|
||||||
|
|
|
||||||
33
system/modules/cockpit.nix
Normal file
33
system/modules/cockpit.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
enableNginx ? false,
|
||||||
|
domain,
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.cockpit = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
allowed-origins = [
|
||||||
|
];
|
||||||
|
settings = {
|
||||||
|
WebService = {
|
||||||
|
ProtocolHeader = "X-Forwarded-Proto";
|
||||||
|
ForwardedForHeader = "X-Forwarded-For";
|
||||||
|
LoginTo = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."${domain}" = mkIf enableNginx {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://localhost:${toString config.services.cockpit.port}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
|
||||||
services.fail2ban = {
|
services.fail2ban = {
|
||||||
enable = true;
|
enable = true;
|
||||||
maxretry = 5;
|
maxretry = 5;
|
||||||
|
|
@ -18,11 +17,7 @@
|
||||||
maxtime = "1y";
|
maxtime = "1y";
|
||||||
overalljails = true;
|
overalljails = true;
|
||||||
};
|
};
|
||||||
jails =
|
jails = {
|
||||||
let
|
|
||||||
nginxLogPath = "/var/log/nginx/error.log*";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sshd.settings = {
|
sshd.settings = {
|
||||||
logPath = "";
|
logPath = "";
|
||||||
filter = "sshd";
|
filter = "sshd";
|
||||||
|
|
@ -33,19 +28,19 @@
|
||||||
maxretry = 5;
|
maxretry = 5;
|
||||||
};
|
};
|
||||||
nginx-error-common.settings = {
|
nginx-error-common.settings = {
|
||||||
logPath = nginxLogPath;
|
logPath = "";
|
||||||
filter = "nginx-error-common";
|
filter = "nginx-error-common";
|
||||||
action = ''nftables-multiport[name=HTTP, port="http,https"]'';
|
action = ''nftables-multiport[name=HTTP, port="http,https"]'';
|
||||||
backend = "auto";
|
backend = "systemd";
|
||||||
findtime = 600;
|
findtime = 600;
|
||||||
bantime = 600;
|
bantime = 600;
|
||||||
maxretry = 5;
|
maxretry = 5;
|
||||||
};
|
};
|
||||||
nginx-forbidden.settings = {
|
nginx-forbidden.settings = {
|
||||||
logPath = nginxLogPath;
|
logPath = "";
|
||||||
filter = "nginx-forbidden";
|
filter = "nginx-forbidden";
|
||||||
action = ''nftables-multiport[name=HTTP, port="http,https"]'';
|
action = ''nftables-multiport[name=HTTP, port="http,https"]'';
|
||||||
backend = "auto";
|
backend = "systemd";
|
||||||
findtime = 600;
|
findtime = 600;
|
||||||
bantime = 600;
|
bantime = 600;
|
||||||
maxretry = 5;
|
maxretry = 5;
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
oci-containers = {
|
oci-containers = {
|
||||||
backend = "docker";
|
backend = "podman";
|
||||||
containers = {
|
containers = {
|
||||||
phpLDAPadmin = {
|
phpLDAPadmin = {
|
||||||
extraOptions = [ "--network=host" ];
|
extraOptions = [ "--network=host" ];
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ in
|
||||||
contacts
|
contacts
|
||||||
calendar
|
calendar
|
||||||
tasks
|
tasks
|
||||||
|
whiteboard
|
||||||
;
|
;
|
||||||
|
|
||||||
camerarawpreviews = pkgs.fetchNextcloudApp {
|
camerarawpreviews = pkgs.fetchNextcloudApp {
|
||||||
|
|
@ -120,74 +121,4 @@ in
|
||||||
exiftool
|
exiftool
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd = {
|
|
||||||
timers = lib.mkIf enableBackup {
|
|
||||||
"nextcloud-backup" = {
|
|
||||||
enable = true;
|
|
||||||
description = "Nextcloud backup";
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "*-*-* 03:00:00";
|
|
||||||
Persistent = true;
|
|
||||||
OnUnitActiveSec = "1d";
|
|
||||||
AccuracySec = "1h";
|
|
||||||
Unit = "nextcloud-backup.service";
|
|
||||||
};
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services."nextcloud-backup" = lib.mkIf enableBackup {
|
|
||||||
enable = true;
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nextcloud";
|
|
||||||
ExecStart =
|
|
||||||
let
|
|
||||||
script = pkgs.writeShellScriptBin "backup" (
|
|
||||||
''
|
|
||||||
nextcloudPath="${config.services.nextcloud.datadir}"
|
|
||||||
|
|
||||||
if [ ! -d "$nextcloudPath" ]; then
|
|
||||||
echo "nextcloud path not found: $nextcloudPath"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
''
|
|
||||||
+ (
|
|
||||||
if dataBackupPath != null then
|
|
||||||
''
|
|
||||||
backupPath="${dataBackupPath}"
|
|
||||||
nextcloudBakPath="$backupPath"
|
|
||||||
|
|
||||||
if [ ! -d "$backupPath" ]; then
|
|
||||||
echo "Backup device is not mounted: $backupPath"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Start syncing..."
|
|
||||||
${pkgs.rsync}/bin/rsync -rh --delete "$nextcloudPath" "$nextcloudBakPath"
|
|
||||||
echo "Data dir backup completed."
|
|
||||||
''
|
|
||||||
else
|
|
||||||
""
|
|
||||||
)
|
|
||||||
+ (
|
|
||||||
if dbBackupPath != null then
|
|
||||||
''
|
|
||||||
nextcloudDBBakPath="${dbBackupPath}/nextcloud-db.bak.tar"
|
|
||||||
if [ ! -d "$nextcloudBakPath" ]; then
|
|
||||||
mkdir -p "$nextcloudBakPath"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Try backing up database (postgresql)"
|
|
||||||
${pkgs.postgresql}/bin/pg_dump -F t nextcloud -f "$nextcloudDBBakPath"
|
|
||||||
echo "Database backup completed."
|
|
||||||
''
|
|
||||||
else
|
|
||||||
""
|
|
||||||
)
|
|
||||||
);
|
|
||||||
in
|
|
||||||
"${script}/bin/backup";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,16 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
username,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
programs.virt-manager.enable = true;
|
|
||||||
users.groups.libvirtd.members = [ username ];
|
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
docker.enable = true;
|
docker.enable = true;
|
||||||
|
|
||||||
# Run container as systemd service
|
# Run container as systemd service
|
||||||
oci-containers = {
|
oci-containers = {
|
||||||
backend = "docker";
|
backend = "podman";
|
||||||
containers = { };
|
containers = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
libvirtd = {
|
|
||||||
enable = true;
|
|
||||||
qemu = {
|
|
||||||
package = pkgs.qemu_kvm;
|
|
||||||
swtpm.enable = true;
|
|
||||||
ovmf.enable = true;
|
|
||||||
ovmf.packages = [ pkgs.OVMFFull.fd ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
spiceUSBRedirection.enable = true;
|
spiceUSBRedirection.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.etc = {
|
|
||||||
"ovmf/edk2-x86_64-secure-code.fd" = {
|
|
||||||
source = config.virtualisation.libvirtd.qemu.package + "/share/qemu/edk2-x86_64-secure-code.fd";
|
|
||||||
};
|
|
||||||
|
|
||||||
"ovmf/edk2-i386-vars.fd" = {
|
|
||||||
source = config.virtualisation.libvirtd.qemu.package + "/share/qemu/edk2-i386-vars.fd";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue