mirror of
https://github.com/SebastianStork/nixos-config.git
synced 2026-01-21 15:11:34 +01:00
Remove host "stratus"
This commit is contained in:
parent
00ce882cb1
commit
8a4ca50606
21 changed files with 0 additions and 856 deletions
|
|
@ -3,7 +3,6 @@ keys:
|
|||
- &alto age1qz04yg4h4g22wxqca2pd5k0z574223f6m5c9jy5ny37nlgcd6u4styf06t
|
||||
- &fern age1sywwrwse76x8yskrsfpwk38fu2cmyx5s9qkf2pgc68cta0vj9psql7dp6e
|
||||
- &north age18x6herevmcuhcmeh47ll6p9ck9zk4ga6gfxwlc8yl49rwjxm7qusylwfgc
|
||||
- &stratus age1pryafed9elaea6zk5gnf6drjt4nznc02385y973lwt9t2s7j7vmsfnggkp
|
||||
|
||||
# Users
|
||||
- &seb-admin age1mpq8m4p7dnxh5ze3fh7etd2k6sp85zdnmp9te3e9chcw4pw07pcq960zh5
|
||||
|
|
@ -27,11 +26,6 @@ creation_rules:
|
|||
- age:
|
||||
- *seb-admin
|
||||
- *north
|
||||
- path_regex: hosts/stratus/secrets.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *seb-admin
|
||||
- *stratus
|
||||
|
||||
# Users
|
||||
- path_regex: users/seb/@fern/secrets.yaml$
|
||||
|
|
|
|||
|
|
@ -39,15 +39,9 @@ in
|
|||
(mkHost "alto")
|
||||
(mkHost "fern")
|
||||
(mkHost "north")
|
||||
(mkHost "stratus")
|
||||
];
|
||||
|
||||
deploy.nodes = {
|
||||
stratus = {
|
||||
hostname = "stratus";
|
||||
sshUser = "root";
|
||||
profiles.system.path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.stratus;
|
||||
};
|
||||
alto = {
|
||||
hostname = "alto";
|
||||
sshUser = "root";
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
in
|
||||
{
|
||||
myConfig.resticBackup.${serviceName} = {
|
||||
enable = true;
|
||||
healthchecks.enable = true;
|
||||
|
||||
extraConfig = {
|
||||
backupPrepareCommand = "${lib.getExe' pkgs.systemd "systemctl"} stop docker-actualbudget.service";
|
||||
backupCleanupCommand = "${lib.getExe' pkgs.systemd "systemctl"} start docker-actualbudget.service docker-tailscale-actualbudget.service";
|
||||
paths = [ "/data/${serviceName}" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "${serviceName}-restore";
|
||||
text = ''
|
||||
systemctl stop docker-actualbudget.service
|
||||
rm -rf /data/${serviceName}
|
||||
restic-${serviceName} restore --target / latest
|
||||
systemctl start docker-actualbudget.service docker-tailscale-actualbudget.service
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "budget";
|
||||
|
||||
serveConfig = builtins.toJSON {
|
||||
TCP."443".HTTPS = true;
|
||||
Web."${subdomain}.${config.networking.domain}:443".Handlers."/".Proxy = "http://127.0.0.1:5006";
|
||||
};
|
||||
configPath = pkgs.writeTextDir "tailscale-serve.json" serveConfig;
|
||||
in
|
||||
{
|
||||
imports = [ ./backup.nix ];
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
${serviceName} = {
|
||||
image = "ghcr.io/actualbudget/actual-server@sha256:0cf0300ed4905045ed87e8892c26fbd83cd08e8499bb81dc28deef6afeb162fb";
|
||||
volumes = [ "/data/${serviceName}:/data" ];
|
||||
};
|
||||
|
||||
"tailscale-${serviceName}" = {
|
||||
environment.TS_HOSTNAME = subdomain;
|
||||
volumes = [ "${configPath}:/config" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
containers = lib.filterAttrs (_: v: v == "directory") (builtins.readDir ./.);
|
||||
in
|
||||
{
|
||||
imports = lib.mapAttrsToList (name: _: ./${name}) containers;
|
||||
|
||||
sops.secrets."container/tailscale-auth-key" = { };
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
|
||||
containers = lib.mapAttrs' (
|
||||
name: _:
|
||||
lib.nameValuePair "tailscale-${name}" {
|
||||
image = "ghcr.io/tailscale/tailscale@sha256:da35f0fbeb3037754049e3b079cb30c58c140576a50b54be107c0ff6ad0ec0e9";
|
||||
environment = {
|
||||
TS_STATE_DIR = "/var/lib/tailscale";
|
||||
TS_SERVE_CONFIG = "/config/tailscale-serve.json";
|
||||
TS_USERSPACE = "true"; # https://github.com/tailscale/tailscale/issues/11372
|
||||
};
|
||||
environmentFiles = [
|
||||
# Contains "TS_AUTHKEY=<token>"
|
||||
config.sops.secrets."container/tailscale-auth-key".path
|
||||
];
|
||||
volumes = [ "/var/lib/tailscale-${name}:/var/lib/tailscale" ];
|
||||
extraOptions = [ "--network=container:${name}" ];
|
||||
dependsOn = [ name ];
|
||||
}
|
||||
) containers;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "office";
|
||||
|
||||
serveConfig = builtins.toJSON {
|
||||
TCP."443".HTTPS = true;
|
||||
Web."${subdomain}.${config.networking.domain}:443".Handlers."/".Proxy = "http://127.0.0.1:80";
|
||||
};
|
||||
configPath = pkgs.writeTextDir "tailscale-serve.json" serveConfig;
|
||||
in
|
||||
{
|
||||
sops.secrets."container/${serviceName}/jwt-secret" = { };
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
${serviceName} = {
|
||||
image = "onlyoffice/documentserver@sha256:3489a54c581414055dd9bfa3890435e5e6fc8c4ce0ffdd65cf3c7869f680cf81";
|
||||
environmentFiles = [
|
||||
# Contains "JWT_SECRET=<token>"
|
||||
config.sops.secrets."container/${serviceName}/jwt-secret".path
|
||||
];
|
||||
};
|
||||
|
||||
"tailscale-${serviceName}" = {
|
||||
environment.TS_HOSTNAME = subdomain;
|
||||
volumes = [ "${configPath}:/config" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "pdf";
|
||||
|
||||
serveConfig = builtins.toJSON {
|
||||
TCP."443".HTTPS = true;
|
||||
Web."${subdomain}.${config.networking.domain}:443".Handlers."/".Proxy = "http://127.0.0.1:8080";
|
||||
};
|
||||
configPath = pkgs.writeTextDir "tailscale-serve.json" serveConfig;
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
${serviceName} = {
|
||||
image = "frooodle/s-pdf@sha256:2a4a1483cd9f84e6af6281d84839ed15bb02d3818f02edad780f59e1c9e22a49";
|
||||
environment = {
|
||||
LANGS = "de_DE";
|
||||
SYSTEM_SHOWUPDATE = "false";
|
||||
};
|
||||
volumes = [
|
||||
"/data/stirling-pdf/tessdata:/usr/share/tessdata"
|
||||
"/data/stirling-pdf/configs:/configs"
|
||||
];
|
||||
};
|
||||
|
||||
"tailscale-${serviceName}" = {
|
||||
environment.TS_HOSTNAME = subdomain;
|
||||
volumes = [ "${configPath}:/config" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
{
|
||||
config,
|
||||
inputs,
|
||||
self,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
containers = lib.filterAttrs (_: v: v == "directory") (builtins.readDir ./.);
|
||||
dataDirOf = name: "/data/${name}";
|
||||
in
|
||||
{
|
||||
imports = lib.mapAttrsToList (name: _: ./${name}) containers;
|
||||
|
||||
sops.secrets = {
|
||||
"container/tailscale-auth-key" = { };
|
||||
"restic/environment" = { };
|
||||
"restic/password" = { };
|
||||
"healthchecks-ping-key" = { };
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = lib.flatten (
|
||||
lib.mapAttrsToList (name: _: [
|
||||
"d ${dataDirOf name} - - -"
|
||||
"d /var/lib/tailscale-${name} - - -"
|
||||
]) containers
|
||||
);
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
bridges.br0.interfaces = [ "eno1" ];
|
||||
interfaces."br0".useDHCP = true;
|
||||
|
||||
nat = {
|
||||
enable = true;
|
||||
internalInterfaces = [ "ve-+" ];
|
||||
externalInterface = "br0";
|
||||
};
|
||||
};
|
||||
|
||||
containers = lib.mapAttrs (name: _: {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
|
||||
privateNetwork = true;
|
||||
enableTun = true;
|
||||
hostBridge = "br0";
|
||||
|
||||
bindMounts = {
|
||||
# Secrets
|
||||
"/run/secrets/tailscale-auth-key".hostPath = "/run/secrets/container/tailscale-auth-key";
|
||||
"/run/secrets/container/${name}".isReadOnly = false;
|
||||
"/run/secrets/restic".isReadOnly = false;
|
||||
"/run/secrets/healthchecks-ping-key".isReadOnly = false;
|
||||
|
||||
# State
|
||||
${dataDirOf name}.isReadOnly = false;
|
||||
"/var/lib/tailscale" = {
|
||||
hostPath = "/var/lib/tailscale-${name}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs self;
|
||||
inherit (config.system) stateVersion;
|
||||
inherit (config.networking) domain;
|
||||
dataDir = dataDirOf name;
|
||||
};
|
||||
config =
|
||||
{
|
||||
self,
|
||||
stateVersion,
|
||||
domain,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [ self.nixosModules.default ];
|
||||
|
||||
system = {
|
||||
inherit stateVersion;
|
||||
};
|
||||
|
||||
networking = {
|
||||
inherit domain;
|
||||
useHostResolvConf = false;
|
||||
interfaces."eth0".useDHCP = true;
|
||||
nameservers = [
|
||||
"8.8.8.8"
|
||||
"1.1.1.1"
|
||||
];
|
||||
};
|
||||
services.resolved.enable = true;
|
||||
|
||||
myConfig.tailscale.enable = true;
|
||||
};
|
||||
}) containers;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
userName = config.services.forgejo.user;
|
||||
groupName = config.services.forgejo.group;
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules = [ "d ${dataDir}/backup 750 ${userName} ${groupName} -" ];
|
||||
|
||||
security.polkit = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.freedesktop.systemd1.manage-units" &&
|
||||
action.lookup("unit") == "forgejo.service" &&
|
||||
subject.user == "forgejo") {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
'';
|
||||
};
|
||||
|
||||
myConfig.resticBackup.${serviceName} = {
|
||||
enable = true;
|
||||
user = userName;
|
||||
healthchecks.enable = true;
|
||||
|
||||
extraConfig = {
|
||||
backupPrepareCommand = ''
|
||||
${lib.getExe' pkgs.systemd "systemctl"} stop forgejo.service
|
||||
${lib.getExe' config.services.postgresql.package "pg_dump"} forgejo --format=custom --file=${dataDir}/backup/db.dump
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
${lib.getExe' pkgs.systemd "systemctl"} start forgejo.service
|
||||
'';
|
||||
paths = [
|
||||
"${dataDir}/home/custom"
|
||||
"${dataDir}/home/data"
|
||||
"${dataDir}/home/repositories"
|
||||
"${dataDir}/home/.ssh"
|
||||
"${dataDir}/backup"
|
||||
];
|
||||
extraBackupArgs = [ "--exclude='${dataDir}/home/custom/conf/app.ini'" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "${serviceName}-restore";
|
||||
text = ''
|
||||
systemctl stop forgejo.service
|
||||
sudo --user=${userName} restic-${serviceName} restore --target / latest
|
||||
sudo --user=${userName} pg_restore --clean --if-exists --dbname forgejo ${dataDir}/backup/db.dump
|
||||
systemctl start forgejo.service
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "git";
|
||||
in
|
||||
{
|
||||
sops.secrets."container/forgejo/admin-password" = { };
|
||||
|
||||
containers.${serviceName}.config =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
userName = config.services.forgejo.user;
|
||||
groupName = config.services.forgejo.group;
|
||||
in
|
||||
{
|
||||
imports = [ ./backup.nix ];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"z /run/secrets/container/forgejo/admin-password - ${userName} ${groupName} -"
|
||||
"d ${dataDir}/home 750 ${userName} ${groupName} -"
|
||||
"d ${dataDir}/postgresql 700 postgres postgres -"
|
||||
];
|
||||
|
||||
services.postgresql.dataDir = "${dataDir}/postgresql";
|
||||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
stateDir = "${dataDir}/home";
|
||||
|
||||
lfs.enable = true;
|
||||
database.type = "postgres";
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = config.networking.fqdn;
|
||||
ROOT_URL = "https://${config.services.forgejo.settings.server.DOMAIN}/";
|
||||
};
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.forgejo.preStart = ''
|
||||
create="${lib.getExe config.services.forgejo.package} admin user create"
|
||||
$create --admin --email "sebastian.stork@pm.me" --username seb --password "$(cat /run/secrets/container/forgejo/admin-password)" || true
|
||||
'';
|
||||
|
||||
myConfig.tailscale = {
|
||||
inherit subdomain;
|
||||
serve = "3000";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "rss";
|
||||
in
|
||||
{
|
||||
sops.secrets."container/freshrss/admin-password" = { };
|
||||
|
||||
containers.${serviceName}.config =
|
||||
{
|
||||
config,
|
||||
domain,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
userName = config.users.users.freshrss.name;
|
||||
groupName = config.users.groups.freshrss.name;
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
"z /run/secrets/container/freshrss/admin-password - ${userName} ${groupName} -"
|
||||
];
|
||||
|
||||
services.freshrss = {
|
||||
enable = true;
|
||||
inherit dataDir;
|
||||
baseUrl = "https://${subdomain}.${domain}";
|
||||
defaultUser = "seb";
|
||||
passwordFile = "/run/secrets/container/freshrss/admin-password";
|
||||
};
|
||||
|
||||
myConfig.tailscale = {
|
||||
inherit subdomain;
|
||||
serve = "80";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
userName = config.users.users.nextcloud.name;
|
||||
groupName = config.users.users.nextcloud.group;
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules = [ "d ${dataDir}/backup 700 ${userName} ${groupName} -" ];
|
||||
|
||||
myConfig.resticBackup.${serviceName} = {
|
||||
enable = true;
|
||||
user = userName;
|
||||
healthchecks.enable = true;
|
||||
|
||||
extraConfig = {
|
||||
backupPrepareCommand = ''
|
||||
${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --on
|
||||
${lib.getExe' config.services.postgresql.package "pg_dump"} nextcloud --format=custom --file=${dataDir}/backup/db.dump
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --off
|
||||
'';
|
||||
paths = [
|
||||
"${dataDir}/home/data"
|
||||
"${dataDir}/home/config/config.php"
|
||||
"${dataDir}/backup"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "${serviceName}-restore";
|
||||
text = ''
|
||||
sudo --user=${userName} ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --on
|
||||
sudo --user=${userName} restic-${serviceName} restore --target / latest
|
||||
sudo --user=${userName} pg_restore --clean --if-exists --dbname nextcloud ${dataDir}/backup/db.dump
|
||||
sudo --user=${userName} ${lib.getExe' config.services.nextcloud.occ "nextcloud-occ"} maintenance:mode --off
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "cloud";
|
||||
in
|
||||
{
|
||||
sops.secrets = {
|
||||
"container/nextcloud/admin-password" = { };
|
||||
"container/nextcloud/gmail-password" = { };
|
||||
};
|
||||
|
||||
containers.${serviceName}.config =
|
||||
{
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
userName = config.users.users.nextcloud.name;
|
||||
groupName = config.users.users.nextcloud.group;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./email-server.nix
|
||||
./backup.nix
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"z /run/secrets/container/nextcloud/admin-password - ${userName} ${groupName} -"
|
||||
"d ${dataDir}/home 750 ${userName} ${groupName} -"
|
||||
"d ${dataDir}/postgresql 700 postgres postgres -"
|
||||
];
|
||||
|
||||
services.postgresql.dataDir = "${dataDir}/postgresql";
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud30;
|
||||
home = "${dataDir}/home";
|
||||
hostName = config.networking.fqdn;
|
||||
|
||||
database.createLocally = true;
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
adminuser = "admin";
|
||||
adminpassFile = "/run/secrets/container/nextcloud/admin-password";
|
||||
};
|
||||
|
||||
https = true;
|
||||
settings = {
|
||||
overwriteProtocol = "https";
|
||||
trusted_domains = [ "${subdomain}.${config.networking.domain}" ];
|
||||
trusted_proxies = [ "127.0.0.1" ];
|
||||
log_type = "file";
|
||||
default_phone_region = "DE";
|
||||
maintenance_window_start = "2"; # UTC
|
||||
defaultapp = "side_menu";
|
||||
};
|
||||
|
||||
configureRedis = true;
|
||||
maxUploadSize = "16G";
|
||||
phpOptions."opcache.interned_strings_buffer" = "16";
|
||||
|
||||
autoUpdateApps = {
|
||||
enable = true;
|
||||
startAt = "04:00:00";
|
||||
};
|
||||
extraApps = {
|
||||
inherit (config.services.nextcloud.package.packages.apps)
|
||||
calendar
|
||||
contacts
|
||||
deck
|
||||
onlyoffice
|
||||
;
|
||||
|
||||
twofactor_totp = pkgs.fetchNextcloudApp {
|
||||
url = inputs.nextcloud-twofactor-totp.outPath;
|
||||
sha256 = inputs.nextcloud-twofactor-totp.narHash;
|
||||
license = "agpl3Plus";
|
||||
unpack = true;
|
||||
};
|
||||
side_menu = pkgs.fetchNextcloudApp {
|
||||
url = inputs.nextcloud-side-menu.outPath;
|
||||
sha256 = inputs.nextcloud-side-menu.narHash;
|
||||
license = "agpl3Plus";
|
||||
unpack = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.ffmpeg ];
|
||||
|
||||
myConfig.tailscale = {
|
||||
inherit subdomain;
|
||||
serve = "80";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
services.nextcloud.settings = {
|
||||
mail_smtpmode = "sendmail";
|
||||
mail_sendmailmode = "pipe";
|
||||
};
|
||||
|
||||
programs.msmtp = {
|
||||
enable = true;
|
||||
accounts.default = {
|
||||
auth = true;
|
||||
tls = true;
|
||||
host = "smtp.gmail.com";
|
||||
port = "587";
|
||||
user = "nextcloud.stork";
|
||||
from = "nextcloud.stork@gmail.com";
|
||||
passwordeval = "cat /run/secrets/container/nextcloud/gmail-password";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
dataDir,
|
||||
...
|
||||
}:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
userName = config.services.paperless.user;
|
||||
groupName = config.users.users.${userName}.group;
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules = [ "d ${dataDir}/backup 700 ${userName} ${groupName} -" ];
|
||||
|
||||
users.users.paperless.extraGroups = [ "redis-paperless" ];
|
||||
|
||||
myConfig.resticBackup.${serviceName} = {
|
||||
enable = true;
|
||||
user = userName;
|
||||
healthchecks.enable = true;
|
||||
|
||||
extraConfig = {
|
||||
backupPrepareCommand = ''
|
||||
${dataDir}/paperless-manage document_exporter ${dataDir}/backup ${
|
||||
lib.concatStringsSep " " [
|
||||
"--compare-checksums"
|
||||
"--delete"
|
||||
"--split-manifest"
|
||||
"--use-filename-format"
|
||||
"--no-progress-bar"
|
||||
]
|
||||
}
|
||||
'';
|
||||
paths = [ "${dataDir}/backup" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "${serviceName}-restore";
|
||||
text = ''
|
||||
sudo --user=${userName} restic-${serviceName} restore --target / latest
|
||||
sudo --user=${userName} ${dataDir}/paperless-manage document_importer ${dataDir}/backup
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
serviceName = lib.last (lib.splitString "/" (builtins.toString ./.)); # Parent directory name
|
||||
subdomain = "paper";
|
||||
in
|
||||
{
|
||||
sops.secrets."container/paperless/admin-password" = { };
|
||||
|
||||
containers.${serviceName}.config =
|
||||
{ dataDir, ... }:
|
||||
{
|
||||
imports = [ ./backup.nix ];
|
||||
|
||||
services.paperless = {
|
||||
enable = true;
|
||||
inherit dataDir;
|
||||
passwordFile = "/run/secrets/container/paperless/admin-password";
|
||||
settings.PAPERLESS_OCR_LANGUAGE = "deu+eng";
|
||||
};
|
||||
|
||||
myConfig.tailscale = {
|
||||
inherit subdomain;
|
||||
serve = "28981";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
imports = [
|
||||
./containers/docker
|
||||
./containers/nspawn
|
||||
];
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
|
||||
myConfig = {
|
||||
sops.enable = true;
|
||||
boot.loader.systemdBoot.enable = true;
|
||||
tailscale = {
|
||||
enable = true;
|
||||
ssh.enable = true;
|
||||
exitNode.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
{
|
||||
disko.devices = {
|
||||
disk =
|
||||
let
|
||||
luks-settings = {
|
||||
settings = {
|
||||
allowDiscards = true;
|
||||
keyFile = "/dev/disk/by-id/usb-SMI_USB_DISK-0:0";
|
||||
keyFileSize = 4096;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
one = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
type = "EF00";
|
||||
size = "512M";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "defaults" ];
|
||||
};
|
||||
};
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
name = "cryptroot";
|
||||
type = "luks";
|
||||
content = {
|
||||
type = "lvm_pv";
|
||||
vg = "root-pool";
|
||||
};
|
||||
} // luks-settings;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
two = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions.luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
name = "cryptdata";
|
||||
type = "luks";
|
||||
content = {
|
||||
type = "lvm_pv";
|
||||
vg = "data-pool";
|
||||
};
|
||||
} // luks-settings;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
lvm_vg = {
|
||||
root-pool = {
|
||||
type = "lvm_vg";
|
||||
lvs.root = {
|
||||
size = "100%FREE";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
mountOptions = [ "defaults" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
data-pool = {
|
||||
type = "lvm_vg";
|
||||
lvs.data = {
|
||||
size = "100%FREE";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/data";
|
||||
mountOptions = [ "defaults" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [ inputs.disko.nixosModules.default ];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
cpu.intel.updateMicrocode = true;
|
||||
};
|
||||
|
||||
boot = {
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
initrd.kernelModules = [ "usb_storage" ];
|
||||
initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"nvme"
|
||||
"sd_mod"
|
||||
];
|
||||
};
|
||||
|
||||
zramSwap.enable = true;
|
||||
services = {
|
||||
thermald.enable = true;
|
||||
fstrim.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
seb-password: ENC[AES256_GCM,data:InhoM7Z63JuEHY3j85aSlNy/DtOlfi38gDGYVJ9Srl5Nf/qgYJhOR4VQAZpoyWbtcNogdO05ddQ6OOzTc9PPHNePP00wz3KWRQ==,iv:rLCKJ9wUL+3sjIaqwV89pYJtt/ERuoR4AAgbt9H4oHg=,tag:toe3ey02D85APFKXlm3mEg==,type:str]
|
||||
tailscale-auth-key: ENC[AES256_GCM,data:wiANABnJ9nzaagyQtccudaquKBnlhF0o87gPRKYFmTmujNQvDth0+tf/C5c0fT+eSxtM/KyJj7ZNwx9swFc=,iv:yq1LWbNE/OQdccX6bsspzbk0FJLtDRVOvLO2kSJvOxQ=,tag:TqNQiU7J16B1/QtfBuOawA==,type:str]
|
||||
container:
|
||||
tailscale-auth-key: ENC[AES256_GCM,data:bmLCx0yhdLQNtxch7OtOfhhW111nnSWEtg4K/1lURcZeUGtgDPjdyhAlcCba7p7QJf+RXZyTdgDKJ/TL8DQ=,iv:gj8/xBwe92MCWcTMYqm427tKom15bBid6tmJSvVopPQ=,tag:EWcGZT3UKUtFQiLkLkulNQ==,type:str]
|
||||
onlyoffice:
|
||||
jwt-secret: ENC[AES256_GCM,data:JTrtVdMJC0U2iw7wJ0ZE2eQGy5rM5BqPHRLE0zQH/iDLAADY0QZP5xc=,iv:4R/1YcVQjLTcEKJbQ5oq1/vUM+dc4zBLkFLSgH4wq0w=,tag:YIg2GV18hm2oYvTS6o6bUQ==,type:str]
|
||||
forgejo:
|
||||
admin-password: ENC[AES256_GCM,data:hBaD9s1EPm6pA+IH7i/ZsNrOTdiGCm5Lb2Hwd3BR,iv:2gmdO1dImo3fZWRaO3oyt3/IfD3zscHwxgv0iwgAMgQ=,tag:9ha9UP8u1ALQUWqpu8o1cw==,type:str]
|
||||
freshrss:
|
||||
admin-password: ENC[AES256_GCM,data:WlF90o4sHHXg2WzDiC/BbyYPpj6VCcmmNYDipl17,iv:8OdmIKQ3AHGUCE83pslrCWk+/IUVBmnjryfw8KrEBUk=,tag:mFEDPlO6uEN5uy70f9V+CQ==,type:str]
|
||||
nextcloud:
|
||||
admin-password: ENC[AES256_GCM,data:5b+Knl8ZFBL2H91FBqG6LGbx7+VqMryQjfQnUGCE,iv:4Nja7A+VyPPBiJP42fhDTWe93MmBo4/X8IMTR5PGo3s=,tag:ii22+1zaaE3MXj+A86Y/Yw==,type:str]
|
||||
gmail-password: ENC[AES256_GCM,data:r/Do22VT42fxR4ZmcsuFia88YYA=,iv:5oVZRC/L9//pA/vqlk79WNoAdHO+c8CVhywYFRC15eA=,tag:2s/G6YDieF+z8ayHo02Jwg==,type:str]
|
||||
paperless:
|
||||
admin-password: ENC[AES256_GCM,data:7eO/qQ4/k9G93yykVyzt6JG0QeE=,iv:rfPMMiCCYxgQa5k+9RWRKpIkkLWamzBg1cIrsGun9G8=,tag:Xe2EOiipIH4gHdCMuw7n+w==,type:str]
|
||||
restic:
|
||||
environment: ENC[AES256_GCM,data:AxcIe2HmqZcjWETidgB63Xh+5pxPJS2BXXFOXAIaqjI+j4Qm/txorgXkY/n8tOJnJWFmVI6vj4Uz8+MFl1rHx0NnjNE3ijutV2gvTsUUtR18JDnW6ks0h7tcuVix4RH7OHU=,iv:+ohpmCKu/KIEn4gcBn3hNDTF7qybQAe3uDWiQ8GAIVw=,tag:OLqmrivfoB+oobTNbbgnVw==,type:str]
|
||||
password: ENC[AES256_GCM,data:IuOdnYu5EqGY0wCFVx86ztNphHO5xTtPDr1UfjA4,iv:XPPs61l6KWGA06uhRZid6rAgNfbHtcJWYjrD5QJrnlI=,tag:y/NgGKwvAO9PtF0qQmTp1Q==,type:str]
|
||||
healthchecks-ping-key: ENC[AES256_GCM,data:hU3X/JiGlToyNW+8Nyo7Jpq7Jiriew==,iv:c+/jK+4SiCby3yKdjXq69PEyfCOhua9quGCj7OK0Nhc=,tag:Od/x0VxsbZwyRbHvjwxHpg==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age1mpq8m4p7dnxh5ze3fh7etd2k6sp85zdnmp9te3e9chcw4pw07pcq960zh5
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZYlNWcmJLSUs0ZG5lM1Bq
|
||||
TnpZVWlhYXdPNVdYZFJDK3NjSTVYS3hQazN3CmRhUnd2WjlvRW12U2dXK2tXQmVW
|
||||
elFOWHNvcXA3VFRGNXlEY2UvdDB2VFkKLS0tIGhsTmU3dTdZenlQbkcyUW85dVJq
|
||||
SFVjcWRWUVJaNkVxZ1RpTUxkcTJYOGsK7BYF7OWVTNwJdbN1cThUlEiAzZwPQyzN
|
||||
AhzAq3SY7g1MBPfbfMq3Seok09CX3TpgwARYdzmWNyytkEKAB31xtQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1pryafed9elaea6zk5gnf6drjt4nznc02385y973lwt9t2s7j7vmsfnggkp
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByQUtwNlc4RDZJQnVYdDBt
|
||||
OFpkSFRybWpSbm5lSW5rMFBuaW9oc0tqZDBZCmxvaWJGc3BkbmdKampyVVQwMjVI
|
||||
Q01UTGNESU1RRjNNdk5tY21zYWRSMUkKLS0tIHVBMUF3Y1B3cXJjRVdqZDNiZTlX
|
||||
b3daaTFONzZ0cUtVY3RHUUhWOE1xRUEK0X59xCmXm8IinpaHonDpo7+3DqnMCX3k
|
||||
zbvxChaurZ1pgZr51B662m9OLhkjrQVnIKK8ujZAJg7TyyQD/UrFUw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-03-26T23:52:03Z"
|
||||
mac: ENC[AES256_GCM,data:ZdLKrA5NPZmr7Oagtu3fbLfJKL1PDHajrqtAvJ7yj9NsgVEnHd8VWo2+NQWhrxqT3D47jDyhCgcZigiYkKc7MDJFFJByXlBCg5hKnN6gBe1tvnYbj7grgFs5SUo9SxuKzeKH3clriyLW1UQQI0tYvHHUuZmG2eAqDX+SHGWRlMs=,iv:2BmmqJyXeJOLwwnIQ5M2NJIqr/ux0DoD85D3VVrBVUk=,tag:gSQV/H98kfjvHQnxmJEIAQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.4
|
||||
|
|
@ -1 +0,0 @@
|
|||
{ imports = [ ../user.nix ]; }
|
||||
Loading…
Add table
Add a link
Reference in a new issue