chore[server]: improve backup management

This commit is contained in:
Leon Schwarzäugl 2025-11-27 16:47:41 +01:00 committed by Leon Schwarzäugl
parent 5b5ef2b9b0
commit 8f833485da
15 changed files with 1394 additions and 631 deletions

39
.github/README.md vendored
View file

@ -150,25 +150,26 @@
### Hosts ### Hosts
| Name | Hardware | Use | | Name | Hardware | Use |
|--------------------|-----------------------------------------------------|------------------------------------------------------| |---------------------|-----------------------------------------------------|-----------------------------------------------------|
|💻 **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop | |💻 **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop |
|💻 **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop | |💻 **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop |
|💻 **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox | |💻 **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox |
|🏠 **treehouse** | NVIDIA DGX Spark | Workstation, AI playground and home-manager reference| |🏠 **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference |
|🖥️ **winters** | ASRock J4105-ITX, 32GB RAM | Secondary homeserver and data storgae | |🖥️ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, datastorage |
|🖥️ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Main homeserver running microvms, data storage | |🖥️ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) |
|🖥️ **hintbooth** | HUNSN RM02, 8GB RAM | Router | |🖥️ **hintbooth** | HUNSN RM02, 8GB RAM | Router |
|☁️ **milkywell** | Oracle Cloud: VM.Standard.E2.1.Micro | Authoritative DNS server | |☁️ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative dns server |
|☁️ **moonside** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services | |☁️ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion |
|☁️ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache | |☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy |
|☁️ **monkeycave** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server | |☁️ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver |
|☁️ **eagleland** | Hetzner Cloud: CX23 | Mail server | |☁️ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services |
|📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone | |☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binarycache |
|💿 **drugstore** | - | ISO installer configuration | |📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone |
|💿 **brickroad** | - | Kexec tarball | |💿 **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts |
|❔ **chaotheatre** | - | Demo config for checking out my configurtion | |💿 **brickroad** | - | Kexec tarball for bootstrapping low-memory machines |
|❔ **toto** | - | Helper configuration for bootstrapping a new system | |❔ **chaotheatre** | - | Demo config for checking out this configuration |
|❔ **toto** | - | Helper configuration for testing purposes |
</details> </details>
## General Nix tips & useful links ## General Nix tips & useful links

View file

@ -230,25 +230,26 @@ The structure of this flake as seen many revisions, however lately I have settle
Here I give a brief overview over the hostmachines that I am using. This is held in markdown so that I can render it into my GitHub README. Here I give a brief overview over the hostmachines that I am using. This is held in markdown so that I can render it into my GitHub README.
#+begin_src markdown :tangle no :noweb-ref hosts #+begin_src markdown :tangle no :noweb-ref hosts
| Name | Hardware | Use | | Name | Hardware | Use |
|--------------------|-----------------------------------------------------|------------------------------------------------------| |---------------------|-----------------------------------------------------|-----------------------------------------------------|
|💻 **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop | |💻 **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop |
|💻 **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop | |💻 **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop |
|💻 **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox | |💻 **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox |
|🏠 **treehouse** | NVIDIA DGX Spark | Workstation, AI playground and home-manager reference| |🏠 **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference |
|🖥️ **winters** | ASRock J4105-ITX, 32GB RAM | Secondary homeserver and data storgae | |🖥️ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, datastorage |
|🖥️ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Main homeserver running microvms, data storage | |🖥️ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) |
|🖥️ **hintbooth** | HUNSN RM02, 8GB RAM | Router | |🖥️ **hintbooth** | HUNSN RM02, 8GB RAM | Router |
|☁️ **milkywell** | Oracle Cloud: VM.Standard.E2.1.Micro | Authoritative DNS server | |☁️ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative dns server |
|☁️ **moonside** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services | |☁️ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion |
|☁️ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache | |☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy |
|☁️ **monkeycave** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server | |☁️ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver |
|☁️ **eagleland** | Hetzner Cloud: CX23 | Mail server | |☁️ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services |
|📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone | |☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binarycache |
|💿 **drugstore** | - | ISO installer configuration | |📱 **magicant** | Samsung Galaxy Z Flip 6 | Phone |
|💿 **brickroad** | - | Kexec tarball | |💿 **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts |
|❔ **chaotheatre** | - | Demo config for checking out my configurtion | |💿 **brickroad** | - | Kexec tarball for bootstrapping low-memory machines |
|❔ **toto** | - | Helper configuration for bootstrapping a new system | |❔ **chaotheatre** | - | Demo config for checking out this configuration |
|❔ **toto** | - | Helper configuration for testing purposes |
#+end_src #+end_src
** Programs ** Programs
@ -371,6 +372,30 @@ If the new machine is home-manager only, perform these steps:
<<fixes>> <<fixes>>
#+end_src #+end_src
#+RESULTS:
#+begin_export html
Currently, these adaptions are made to the configuration to account for bugs in upstream repos:
- 202501102:
- flake:
- emacs-overlay:
- : version pinned because emacsclient is currently broken on latest
- niri-flake:
- currently not using the sugared version of screenshot-[,window], as it is currently broken
- home-manager:
- emacs-tramp:
- using stable version in extraPackages (broken in unstable)
- :ensure nil in emacs tramp settings to use package in extraPackages
- emacs-calfwL
- pinned to version not in nixpkgs (is in latest emacs-overlay, but that is broken)
- vesktop:
- running stable version (broken in unstable)
- batgrep:
- running stable version (broken in unstable)
- swayosd:
- pinned to version not in nixpkgs (fixes https://github.com/ErikReider/SwayOSD/issues/175)
#+end_export
* flake.nix * flake.nix
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: h:c7588c0d-2528-485d-b2df-04d6336428d7 :CUSTOM_ID: h:c7588c0d-2528-485d-b2df-04d6336428d7
@ -2650,6 +2675,20 @@ This is my main server that I run at home. It handles most tasks that require bi
proxyHost = "moonside"; proxyHost = "moonside";
server = { server = {
inherit (config.repo.secrets.local.networking) localNetwork; inherit (config.repo.secrets.local.networking) localNetwork;
restic = {
bucketName = "SwarselWinters";
paths = [
"/Vault/data/paperless"
"/Vault/data/koillection"
"/Vault/data/postgresql"
"/Vault/data/firefly-iii"
"/Vault/data/radicale"
"/Vault/data/matrix-synapse"
"/Vault/Eternor/Paperless"
"/Vault/Eternor/Bilder"
"/Vault/Eternor/Immich"
];
};
garage = { garage = {
data_dir = { data_dir = {
capacity = "200G"; capacity = "200G";
@ -3366,7 +3405,7 @@ My phone. I use only a minimal config for remote debugging here.
:END: :END:
#+begin_src nix-ts :tangle hosts/home/aarch64-linux/treehouse/default.nix #+begin_src nix-ts :tangle hosts/home/aarch64-linux/treehouse/default.nix
{ self, ... }: { self, pkgs, ... }:
{ {
imports = [ imports = [
@ -3384,11 +3423,15 @@ My phone. I use only a minimal config for remote debugging here.
}; };
}; };
home.packages = with pkgs; [
attic-client
];
# programs.zsh.initContent = " # programs.zsh.initContent = "
# export GPG_TTY=\"$(tty)\" # export GPG_TTY=\"$(tty)\"
# export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) # export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
# gpgconf --launch gpg-agent # gpgconf --launch gpg-agent
# "; # ";
swarselmodules.pii = true;
swarselsystems = { swarselsystems = {
isLaptop = false; isLaptop = false;
@ -3571,6 +3614,12 @@ This machine mainly acts as my proxy server to stand before my local machines.
proxyHost = "moonside"; proxyHost = "moonside";
server = { server = {
inherit (config.repo.secrets.local.networking) localNetwork; inherit (config.repo.secrets.local.networking) localNetwork;
restic = {
bucketName = "SwarselMoonside";
paths = [
"/persist/opt/minecraft"
];
};
}; };
syncthing = { syncthing = {
serviceDomain = config.repo.secrets.common.services.domains.syncthing3; serviceDomain = config.repo.secrets.common.services.domains.syncthing3;
@ -3588,6 +3637,8 @@ This machine mainly acts as my proxy server to stand before my local machines.
shlink = true; shlink = true;
slink = true; slink = true;
syncthing = true; syncthing = true;
minecraft = true;
restic = true;
diskEncryption = lib.mkForce false; diskEncryption = lib.mkForce false;
}; };
} }
@ -9918,6 +9969,7 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml=
:END: :END:
This manages backups for my pictures and obsidian files. This manages backups for my pictures and obsidian files.
Note: you still need to run =restic-<name> init= once on the host to get the bucket running.
#+begin_src nix-ts :tangle modules/nixos/server/restic.nix #+begin_src nix-ts :tangle modules/nixos/server/restic.nix
{ lib, pkgs, config, ... }: { lib, pkgs, config, ... }:
@ -9926,6 +9978,14 @@ This manages backups for my pictures and obsidian files.
in in
{ {
options.swarselmodules.server.restic = lib.mkEnableOption "enable restic backups on server"; options.swarselmodules.server.restic = lib.mkEnableOption "enable restic backups on server";
options.swarselsystems.server.restic = {
bucketName = lib.mkOption {
type = lib.types.str;
};
paths = lib.mkOption {
type = lib.types.listOf lib.types.str;
};
};
config = lib.mkIf config.swarselmodules.server.restic { config = lib.mkIf config.swarselmodules.server.restic {
sops = { sops = {
@ -9948,20 +10008,10 @@ This manages backups for my pictures and obsidian files.
in in
{ {
backups = { backups = {
SwarselWinters = { "${config.swarselsystems.server.restic.bucketName}" = {
environmentFile = config.sops.templates."restic-env".path; environmentFile = config.sops.templates."restic-env".path;
passwordFile = config.sops.secrets.resticpw.path; passwordFile = config.sops.secrets.resticpw.path;
paths = [ inherit (config.swarselsystems.server.restic) paths;
"/Vault/data/paperless"
"/Vault/data/koillection"
"/Vault/data/postgresql"
"/Vault/data/firefly-iii"
"/Vault/data/radicale"
"/Vault/data/matrix-synapse"
"/Vault/Eternor/Paperless"
"/Vault/Eternor/Bilder"
"/Vault/Eternor/Immich"
];
pruneOpts = [ pruneOpts = [
"--keep-daily 3" "--keep-daily 3"
"--keep-weekly 2" "--keep-weekly 2"
@ -13038,9 +13088,11 @@ or 2) use classic path addressing =aws s3 cp <local file> s3://<bucket>/<path to
:END: :END:
#+begin_src nix-ts :tangle modules/nixos/server/minecraft/default.nix #+begin_src nix-ts :tangle modules/nixos/server/minecraft/default.nix
{ lib, config, globals, dns, confLib, ... }: { lib, config, pkgs, globals, dns, confLib, ... }:
let let
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/var/lib/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6; inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
inherit (config.swarselsystems) mainUser;
worldName = "${mainUser}craft";
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -13070,9 +13122,9 @@ or 2) use classic path addressing =aws s3 cp <local file> s3://<bucket>/<path to
serviceConfig = { serviceConfig = {
User = "root"; User = "root";
WorkingDirectory = "/var/lib/minecraft/swarselcraft"; WorkingDirectory = "${serviceDir}/${worldName}";
ExecStart = "/usr/bin/java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui"; ExecStart = "${lib.getExe pkgs.temurin-jre-bin-17} @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
Restart = "always"; Restart = "always";
RestartSec = 30; RestartSec = 30;
@ -14093,10 +14145,10 @@ This section sets up all the imports that are used in the home-manager section.
Again, we adapt =nix= to our needs, enable the home-manager command for non-NixOS machines (NixOS machines are using it as a module) and setting user information that I always keep the same. Again, we adapt =nix= to our needs, enable the home-manager command for non-NixOS machines (NixOS machines are using it as a module) and setting user information that I always keep the same.
#+begin_src nix-ts :tangle modules/home/common/settings.nix #+begin_src nix-ts :tangle modules/home/common/settings.nix
{ self, outputs, lib, pkgs, config, globals, nixosConfig ? config, ... }: { self, outputs, lib, pkgs, config, globals, confLib, ... }:
let let
inherit (config.swarselsystems) mainUser flakePath isNixos isLinux; inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
inherit (nixosConfig.repo.secrets.common) atticPublicKey; inherit (confLib.getConfig.repo.secrets.common) atticPublicKey;
in in
{ {
options.swarselmodules.general = lib.mkEnableOption "general nix settings"; options.swarselmodules.general = lib.mkEnableOption "general nix settings";
@ -14118,7 +14170,7 @@ Again, we adapt =nix= to our needs, enable the home-manager command for non-NixO
}; };
in in
'' ''
plugin-files = ${nix-plugins}/lib/nix/plugins plugin-files = ${nix-plugins}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix} extra-builtins-file = ${self + /nix/extra-builtins.nix}
''; '';
settings = { settings = {
@ -14129,12 +14181,12 @@ Again, we adapt =nix= to our needs, enable the home-manager command for non-NixO
"cgroups" "cgroups"
"pipe-operators" "pipe-operators"
]; ];
substituters = [ substituters = [
"https://${globals.services.attic.domain}/${mainUser}" "https://${globals.services.attic.domain}/${mainUser}"
]; ];
trusted-public-keys = [ trusted-public-keys = [
atticPublicKey atticPublicKey
]; ];
trusted-users = [ "@wheel" "${mainUser}" ]; trusted-users = [ "@wheel" "${mainUser}" ];
connect-timeout = 5; connect-timeout = 5;
bash-prompt-prefix = "$SHLVL:\\w "; bash-prompt-prefix = "$SHLVL:\\w ";
@ -15093,6 +15145,7 @@ Eza provides me with a better =ls= command and some other useful aliases.
programs.atuin = { programs.atuin = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true;
settings = { settings = {
auto_sync = true; auto_sync = true;
sync_frequency = "5m"; sync_frequency = "5m";
@ -15467,7 +15520,10 @@ Currently I only use it as before with =initExtra= though.
}; };
history = { history = {
expireDuplicatesFirst = true; expireDuplicatesFirst = true;
path = "$HOME/.histfile"; append = true;
ignoreSpace = true;
ignoreDups = true;
path = "${config.home.homeDirectory}/.histfile";
save = 100000; save = 100000;
size = 100000; size = 100000;
}; };
@ -15548,15 +15604,23 @@ Currently I only use it as before with =initExtra= though.
#+begin_src nix-ts :tangle modules/home/common/bash.nix #+begin_src nix-ts :tangle modules/home/common/bash.nix
{ config, pkgs, lib, ... }: { config, lib, ... }:
{ {
options.swarselmodules.bash = lib.mkEnableOption "bash settings"; options.swarselmodules.bash = lib.mkEnableOption "bash settings";
config = lib.mkIf config.swarselmodules.bash { config = lib.mkIf config.swarselmodules.bash {
programs.bash = { programs.bash = {
bashrcExtra = '' enable = true;
export PATH="${pkgs.nix}/bin:$PATH" # needed for remote builders
bashrcExtra = lib.mkIf (!config.swarselsystems.isNixos) ''
export PATH="/nix/var/nix/profiles/default/bin:$PATH"
''; '';
historyFile = "${config.home.homeDirectory}/.histfile";
historySize = 100000;
historyFileSize = 100000;
historyControl = [
"ignoreboth"
];
}; };
}; };
} }
@ -20982,34 +21046,36 @@ In short, the options defined here are passed to the modules systems using =_mod
:CUSTOM_ID: h:a33322d5-014a-4072-a4a5-91bc71c343b8 :CUSTOM_ID: h:a33322d5-014a-4072-a4a5-91bc71c343b8
:END: :END:
#+begin_src nix-ts :noweb yes :tangle modules/shared/config-lib.nix #+begin_src nix-ts :noweb yes :tangle modules/shared/config-lib.nix
{ config, lib, globals, ... }: { config, lib, globals, ... }:
{ {
_module.args = { _module.args = {
confLib = rec { confLib = rec {
addressDefault = if config.swarselsystems.proxyHost != config.node.name then globals.networks."${if config.swarselsystems.isCloud then config.node.name else "home"}-${config.swarselsystems.server.localNetwork}".hosts.${config.node.name}.ipv4 else "localhost"; addressDefault = if config.swarselsystems.proxyHost != config.node.name then globals.networks."${if config.swarselsystems.isCloud then config.node.name else "home"}-${config.swarselsystems.server.localNetwork}".hosts.${config.node.name}.ipv4 else "localhost";
domainDefault = service: config.repo.secrets.common.services.domains.${service}; domainDefault = service: config.repo.secrets.common.services.domains.${service};
proxyDefault = config.swarselsystems.proxyHost; proxyDefault = config.swarselsystems.proxyHost;
gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { getConfig = config;
servicePort = port;
serviceName = name; gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec {
specificServiceName = "${name}-${config.node.name}"; servicePort = port;
serviceUser = user; serviceName = name;
serviceGroup = group; specificServiceName = "${name}-${config.node.name}";
serviceDomain = domain; serviceUser = user;
baseDomain = lib.swarselsystems.getBaseDomain domain; serviceGroup = group;
subDomain = lib.swarselsystems.getSubDomain domain; serviceDomain = domain;
serviceDir = dir; baseDomain = lib.swarselsystems.getBaseDomain domain;
serviceAddress = address; subDomain = lib.swarselsystems.getSubDomain domain;
serviceProxy = proxy; serviceDir = dir;
proxyAddress4 = globals.hosts.${proxy}.wanAddress4; serviceAddress = address;
proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null; serviceProxy = proxy;
}; proxyAddress4 = globals.hosts.${proxy}.wanAddress4;
proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null;
}; };
}; };
} };
}
#+end_src #+end_src
*** Packages *** Packages

View file

@ -1,4 +1,4 @@
{ self, ... }: { self, pkgs, ... }:
{ {
imports = [ imports = [
@ -16,11 +16,15 @@
}; };
}; };
home.packages = with pkgs; [
attic-client
];
# programs.zsh.initContent = " # programs.zsh.initContent = "
# export GPG_TTY=\"$(tty)\" # export GPG_TTY=\"$(tty)\"
# export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) # export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
# gpgconf --launch gpg-agent # gpgconf --launch gpg-agent
# "; # ";
swarselmodules.pii = true;
swarselsystems = { swarselsystems = {
isLaptop = false; isLaptop = false;

View file

@ -140,6 +140,12 @@ in
proxyHost = "moonside"; proxyHost = "moonside";
server = { server = {
inherit (config.repo.secrets.local.networking) localNetwork; inherit (config.repo.secrets.local.networking) localNetwork;
restic = {
bucketName = "SwarselMoonside";
paths = [
"/persist/opt/minecraft"
];
};
}; };
syncthing = { syncthing = {
serviceDomain = config.repo.secrets.common.services.domains.syncthing3; serviceDomain = config.repo.secrets.common.services.domains.syncthing3;
@ -157,6 +163,8 @@ in
shlink = true; shlink = true;
slink = true; slink = true;
syncthing = true; syncthing = true;
minecraft = true;
restic = true;
diskEncryption = lib.mkForce false; diskEncryption = lib.mkForce false;
}; };
} }

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:2BVykBGxqpEx6OGG4//MRHDPfE9xJYatb96gn/NXlaYC5nI8zm/9etMRqX6VWEMLdc+4szrCzwNnJx07P6fvY7psER+kd0iuuJc3dLwpm708/fDMP1eOblL0SpIEOHuw8khxtB8KwwMFrwI+858vJvek0/EGN9owCotseJY0lPfX3Kz1StdEspwf0cNAEtck0sQ8MxyODMQggei1eBpr7R+8KRlMg2hBvKw+KbL4C+05twtno3Emar36aeYZurXplm6Z9o3mhvRbpjAkC4cdv9ffiiqQdRuqD0SIbmswjq2ntAVoike6Go0Gflld8POQvE3inZ0pQFC4khTdsheC7nwkI9eudQbNIPzoGq0tjlF4n+/PWgQwoxDiNFvKuKAMrVaAIjQlflt483ofq+TubC9P6FqyjW1gAI94976RIyoBKWWKvJBfr8WKDbwKErLFeTyCnNci96Uctvw4ivYohBj4bUfrZ2zyQk/Y0u7cJYl6qbb+lT1TwHw2Fe9kbn9dDA0wwck5vh0c+q9nhaSG1QNNWxr62w/UyQL/vDxYv1SF5/CwTRmTxDobjhJu+tkzSAfitJ4d41c4/vZ25fG3wehgdLJsdhrjL1JB8smDs/GOFetFO6vPkHZq8HYUc5JB4lg/v9WFXE+nACaFHcZlISrOV9Eh4dG/xu2hsd/rh1uldBVqEZq39PiTk1y94m6AyeQ+dtmGvgBbAFvIpQfUB4+4f7+qO2yQqbb2R/RuqKUuyt+Yy5DrcciFTivGXmlHvC3Cz/qmtpI19boXwiF1uNzKDUHebvK1+azOc2qxOsM15g+jZG9V23o/kP4sGTY9dXqeuMmfELvBBrPgBB8Nhgdi0DrDed4cpQEp2E+rSGCM7V1IdEFa4iMyC8jJ8xq9eBnluNMdmvC8iWanhO7R4AiMzd2JOQImJ11ZX0QAxgG4FwyvYxyX+QXgIHuJDqUVsMxba6HWqwEU0B4qjgVJUDuf0WZxLNBh8bbjH8pV0sa8c7fJBTdHg8X5MBbbaSsYDxQBhdTVKiUXoG5T/2npr1Efjlr09JDbtZlzWYkNfhJ9gLyQI54hXJ0DHWvtnydzHGLKwsPSXRjFcf/jGgCZr2FideArza5y53HBqz2NSOvzvYgZp/avhNumKRQroFZ930Rx2UJoSI+VNDQiPe1aZpOdFsmS923vxlCg/EC0dElKHt0Ou/RRZeonMAmrqak+JIF1+dWn9k2cNNQ=,iv:aP0jgnZRCiLE+BFimZk7k4ElQmPIeZPOvZnc/96j2zs=,tag:0UQF0LlWWGI9tF0UKf8eIA==,type:str]", "data": "ENC[AES256_GCM,data:jGfSfCOqW+p24TaH0vlcNImiY/Pu9YhdIwri4N4RvG64f1fmfNV3z6LmoShCYBfIWF2P7DvOa92dPY2ek9UiC1bEmiMtc/scpGxpir4WNuMLUtMWb0IGmnhtzq7fRAH5FkYLJBSW7pAgVsoajRGbo8Dbk5Dqcm75Pfj2YcC79oAckYt3vSzBcskgJ+ccdCfJ6vDlnAilay/GatZbIQmbEefOi9Rplfln8Ounj/hH+Z6zat04+rI5Lj8bTPu7NOeUlUmgoApuJSFafTb3zgxqnvQL5axOgIaJqiXFWhIf5httmu0mjhJupMXxt14IXgKe+ESAZFF8hWHHUNOpE8gEt5tPRQ1hqA7eHoGSYCrEQK9rSXRweO9LCfGV1+UduXgX1hKgwKDS4A5u69MvcpXQoSYX33ZzuwY7tbykb1tbEb3jN2BOSCBB2ZKHRfsTMqAHTE1RekcBArMxp7+8BkM/oww8RTMJ3I8tcU3QAr/LoFvKwvfIVrbT9gSlKSZUeoBc0WMzmRdjXhAZmQe2pb/TOFmPm31ih/E98zKA8PXhNrqjzEVN99lfn/NKsOLd9a8LXK8XoTTueTWqENEdJRx6dHpWuqBy5GdkrDVCRzgiO3Hpkwg56nPmCGoD5o1IgnRLJItNYrIRejIRaISjlefpezCMYIGMIx+CusvAwiOuuWT6kNfDnaK1U4P3Ndk39lsz8Eg2GMruc4VZ3kpTCeQdvbl/jmFwNMPtzJYooiDualIAL95iZU+RW/K+2g3ZA/Q/gJrc+hB6I+z3PzMod5015Oj0FG97XQzn2TeBD1fuO8UtyxSNajGD3ZK3Laa5QrSNUrzlf7YONSn98Z8OqKsAz+D/vnr0Lg4kjrrhYvN6GpR/QqMnNZT7m4d/oxACDycao6ZUDNE/dvuXSA4nSJp+5cxDXjgSMhnOgS7/gCiLhEBkLwzwdexT/e5vGcqqMmyeMK8vSFsPpRoPv26nsyRalwctY2ClX5KrEEckHNf+p9djB7eJDyLxXkPRLm0yp3dcmcEyk0tUffpcJ6zqWnlm46yfAf29fmIJfQWJ8ehSY+bYwDnx2LmCPcfH+sRSSV2Y1Ay22ry9rVJU88SuRdSPsHOitCuu0TQU56Su0wG24ilh6Bq4Dk+0JxlL3wyPWsnoaYvaRiJ6cs3j0tTwwxepbwiakLzWnVcqHDSoQ+Bn0T4CmcF5ztmpuLZSe/UXA48k77JmbT8vne0ig+kVfRuKhG+qV6g+GnxTIPPXGzQ1hWTS3Fg8YBMt1XYyjX3xa218agvPwLhCru1v3dAfHKk6N8G6SN6EN78RQmJApjSHAGFO,iv:a18hH0e5s4BTTlVIkQT34z8a2jELj59ZHhBbb93o3t0=,tag:sj4baRiZic6sWnJXjhL7TQ==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YjdYNFF5Q1VzQTZ0WU1z\nN2R6cEVObU9RMXdpd2x0Mjh2cmpvY0VvNjE4CmF5Sm1vZWRoOTFIY2pkQUVRQ3FY\nVEd3eGpCbGQ3cUpvTE9JdjJMWnQvckEKLS0tIFRpZDZ1ZGZKaXpObFhZVlNqV0hB\nT20rRGV6S3gvWkZLUzQzVVNGQWNGVkUK0bAeRuI0vb7MJTtpxuD56nwZAk39sHAa\njEhntqsV9ts1Vbw2f0mZEqDdzd64NTtDm/YIwygZ2udV27mXNhVUVw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YjdYNFF5Q1VzQTZ0WU1z\nN2R6cEVObU9RMXdpd2x0Mjh2cmpvY0VvNjE4CmF5Sm1vZWRoOTFIY2pkQUVRQ3FY\nVEd3eGpCbGQ3cUpvTE9JdjJMWnQvckEKLS0tIFRpZDZ1ZGZKaXpObFhZVlNqV0hB\nT20rRGV6S3gvWkZLUzQzVVNGQWNGVkUK0bAeRuI0vb7MJTtpxuD56nwZAk39sHAa\njEhntqsV9ts1Vbw2f0mZEqDdzd64NTtDm/YIwygZ2udV27mXNhVUVw==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-11-24T23:21:12Z", "lastmodified": "2025-11-27T14:12:09Z",
"mac": "ENC[AES256_GCM,data:qf8XNu9bUnwXh/XDMR/2MKf2HKfpqA9GhKjOln97kU57jqqTLxQkdjIwazwoNxEkVkiXHwSd0J/0ZblqcJoCGgy90PC6nYktxRG5y8c462P6Xv259xfpLFTtxtV9Q/Wg18QOruZzULO6ENYTAXGsPZ46VEpf7HQng03PFe9WtlA=,iv:kI2HHNcMjCC5jzI2EAh1nh86HYj7fb11EPkclhIsHSY=,tag:zeWbqVq0c+GzUdJpvcJeEw==,type:str]", "mac": "ENC[AES256_GCM,data:6CqpegjS90H6fAllBsvz3d/y4MpNyMUo+v1sby4hHHw36GlQvnULHuv8dhXrlYaE+L21aoz1RITl7IEtNl/R8zjGh8b0dGIc2iUa2M5dNvHNPMTuucAEQPuEEvTiwI72winpEkdB86fHFFHvBwHwmlNVFJYx5b9bNlpjCofewQI=,iv:qOv8s8j5jOtcoKzgN/HkXvIsS/sk/DFZ4lcEKBLsrKA=,tag:ifXbcFGzpJ+DSJPkvaX0pw==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-06-13T20:12:55Z", "created_at": "2025-06-13T20:12:55Z",

View file

@ -28,6 +28,20 @@
proxyHost = "moonside"; proxyHost = "moonside";
server = { server = {
inherit (config.repo.secrets.local.networking) localNetwork; inherit (config.repo.secrets.local.networking) localNetwork;
restic = {
bucketName = "SwarselWinters";
paths = [
"/Vault/data/paperless"
"/Vault/data/koillection"
"/Vault/data/postgresql"
"/Vault/data/firefly-iii"
"/Vault/data/radicale"
"/Vault/data/matrix-synapse"
"/Vault/Eternor/Paperless"
"/Vault/Eternor/Bilder"
"/Vault/Eternor/Immich"
];
};
garage = { garage = {
data_dir = { data_dir = {
capacity = "200G"; capacity = "200G";

1672
index.html

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,7 @@ in
programs.atuin = { programs.atuin = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableBashIntegration = true;
settings = { settings = {
auto_sync = true; auto_sync = true;
sync_frequency = "5m"; sync_frequency = "5m";

View file

@ -1,12 +1,20 @@
{ config, pkgs, lib, ... }: { config, lib, ... }:
{ {
options.swarselmodules.bash = lib.mkEnableOption "bash settings"; options.swarselmodules.bash = lib.mkEnableOption "bash settings";
config = lib.mkIf config.swarselmodules.bash { config = lib.mkIf config.swarselmodules.bash {
programs.bash = { programs.bash = {
bashrcExtra = '' enable = true;
export PATH="${pkgs.nix}/bin:$PATH" # needed for remote builders
bashrcExtra = lib.mkIf (!config.swarselsystems.isNixos) ''
export PATH="/nix/var/nix/profiles/default/bin:$PATH"
''; '';
historyFile = "${config.home.homeDirectory}/.histfile";
historySize = 100000;
historyFileSize = 100000;
historyControl = [
"ignoreboth"
];
}; };
}; };
} }

View file

@ -1,7 +1,7 @@
{ self, outputs, lib, pkgs, config, globals, nixosConfig ? config, ... }: { self, outputs, lib, pkgs, config, globals, confLib, ... }:
let let
inherit (config.swarselsystems) mainUser flakePath isNixos isLinux; inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
inherit (nixosConfig.repo.secrets.common) atticPublicKey; inherit (confLib.getConfig.repo.secrets.common) atticPublicKey;
in in
{ {
options.swarselmodules.general = lib.mkEnableOption "general nix settings"; options.swarselmodules.general = lib.mkEnableOption "general nix settings";
@ -23,7 +23,7 @@ in
}; };
in in
'' ''
plugin-files = ${nix-plugins}/lib/nix/plugins plugin-files = ${nix-plugins}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix} extra-builtins-file = ${self + /nix/extra-builtins.nix}
''; '';
settings = { settings = {

View file

@ -67,7 +67,10 @@ in
}; };
history = { history = {
expireDuplicatesFirst = true; expireDuplicatesFirst = true;
path = "$HOME/.histfile"; append = true;
ignoreSpace = true;
ignoreDups = true;
path = "${config.home.homeDirectory}/.histfile";
save = 100000; save = 100000;
size = 100000; size = 100000;
}; };

View file

@ -1,6 +1,8 @@
{ lib, config, globals, dns, confLib, ... }: { lib, config, pkgs, globals, dns, confLib, ... }:
let let
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/var/lib/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6; inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
inherit (config.swarselsystems) mainUser;
worldName = "${mainUser}craft";
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -30,9 +32,9 @@ in
serviceConfig = { serviceConfig = {
User = "root"; User = "root";
WorkingDirectory = "/var/lib/minecraft/swarselcraft"; WorkingDirectory = "${serviceDir}/${worldName}";
ExecStart = "/usr/bin/java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui"; ExecStart = "${lib.getExe pkgs.temurin-jre-bin-17} @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
Restart = "always"; Restart = "always";
RestartSec = 30; RestartSec = 30;

View file

@ -4,6 +4,14 @@ let
in in
{ {
options.swarselmodules.server.restic = lib.mkEnableOption "enable restic backups on server"; options.swarselmodules.server.restic = lib.mkEnableOption "enable restic backups on server";
options.swarselsystems.server.restic = {
bucketName = lib.mkOption {
type = lib.types.str;
};
paths = lib.mkOption {
type = lib.types.listOf lib.types.str;
};
};
config = lib.mkIf config.swarselmodules.server.restic { config = lib.mkIf config.swarselmodules.server.restic {
sops = { sops = {
@ -26,20 +34,10 @@ in
in in
{ {
backups = { backups = {
SwarselWinters = { "${config.swarselsystems.server.restic.bucketName}" = {
environmentFile = config.sops.templates."restic-env".path; environmentFile = config.sops.templates."restic-env".path;
passwordFile = config.sops.secrets.resticpw.path; passwordFile = config.sops.secrets.resticpw.path;
paths = [ inherit (config.swarselsystems.server.restic) paths;
"/Vault/data/paperless"
"/Vault/data/koillection"
"/Vault/data/postgresql"
"/Vault/data/firefly-iii"
"/Vault/data/radicale"
"/Vault/data/matrix-synapse"
"/Vault/Eternor/Paperless"
"/Vault/Eternor/Bilder"
"/Vault/Eternor/Immich"
];
pruneOpts = [ pruneOpts = [
"--keep-daily 3" "--keep-daily 3"
"--keep-weekly 2" "--keep-weekly 2"

View file

@ -8,6 +8,8 @@
domainDefault = service: config.repo.secrets.common.services.domains.${service}; domainDefault = service: config.repo.secrets.common.services.domains.${service};
proxyDefault = config.swarselsystems.proxyHost; proxyDefault = config.swarselsystems.proxyHost;
getConfig = config;
gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec {
servicePort = port; servicePort = port;
serviceName = name; serviceName = name;

View file

@ -14,6 +14,10 @@ microbin-admin-password: ENC[AES256_GCM,data:+UyWJAsQ4Jd5iJgdepJ/m9OvkEewLKQz+A=
microbin-uploader-password: ENC[AES256_GCM,data:20QOWTMLS7iTS/Q=,iv:EuUYcY1l4ykKjWvCA0bpXPU0033jlQ8qjYyqSuLAQl0=,tag:Ka5gWBajMdeZS25AajToiA==,type:str] microbin-uploader-password: ENC[AES256_GCM,data:20QOWTMLS7iTS/Q=,iv:EuUYcY1l4ykKjWvCA0bpXPU0033jlQ8qjYyqSuLAQl0=,tag:Ka5gWBajMdeZS25AajToiA==,type:str]
#ENC[AES256_GCM,data:ZnMVMv6M,iv:z53BHIVvMUfYseftc6DTU9Mlb9ywEvNHv24TvIZiMFI=,tag:QdeWjrw0pmJsXYobADzA1A==,type:comment] #ENC[AES256_GCM,data:ZnMVMv6M,iv:z53BHIVvMUfYseftc6DTU9Mlb9ywEvNHv24TvIZiMFI=,tag:QdeWjrw0pmJsXYobADzA1A==,type:comment]
shlink-api: ENC[AES256_GCM,data:XdfDJMjyhJyeqVB4RKgCdkWT2nYC/Pw21D8H/JzkGLuwGx8Q,iv:zucJGNLX8018gD34NL/BwTe0fPFucqpBtMCYXd3IGHs=,tag:/sN/ayEhUaCPmu6fS+mMHQ==,type:str] shlink-api: ENC[AES256_GCM,data:XdfDJMjyhJyeqVB4RKgCdkWT2nYC/Pw21D8H/JzkGLuwGx8Q,iv:zucJGNLX8018gD34NL/BwTe0fPFucqpBtMCYXd3IGHs=,tag:/sN/ayEhUaCPmu6fS+mMHQ==,type:str]
#ENC[AES256_GCM,data:R5mm4WAJww==,iv:6Uyb7Qtl6vt7nur/NLBlrVtKoPkF3ZjXdAhT24HW/ug=,tag:6X9b1zZbpHoEZmaYb9NQSw==,type:comment]
resticpw: ENC[AES256_GCM,data:PcrDphqR5Pin2hM=,iv:lnMlqwyCvbH75qbL2eJYblmuFOaVMmbPHjZ5l0n2Glw=,tag:YUxadLufJ2VPghLded851A==,type:str]
resticaccesskey: ENC[AES256_GCM,data:DOp2cFy1Y5HyXcsQ5O3nsrEOQBtlQQ3P8Q==,iv:0X6HF9kbPNDmhtENHgFeOSHln6xlCf5DNJfqavucDWI=,tag:+THGH00yBT9RhvJtENco2Q==,type:str]
resticsecretaccesskey: ENC[AES256_GCM,data:qpPTWx16Z92cup6ACh2KQPeIk8KPasQB4e/SwxUxfA==,iv:EqWTKXXA7wyArlF+D33tKF37tz8/ORsjsWjRPYBWPqg=,tag:F21+4cL/cozDIene7UQcyA==,type:str]
sops: sops:
age: age:
- recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh - recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh
@ -25,8 +29,8 @@ sops:
bURRem1aY203VW0ya0tZWUY3WTJLQ3MKonflaevgNP91G1cVgzoE6/K800kyG6BK bURRem1aY203VW0ya0tZWUY3WTJLQ3MKonflaevgNP91G1cVgzoE6/K800kyG6BK
Goe81HCYFfm86pzv5wV3/38j7fTZNeZnKwPFkMgEUueF1kA8J9V5CA== Goe81HCYFfm86pzv5wV3/38j7fTZNeZnKwPFkMgEUueF1kA8J9V5CA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-08-12T09:24:55Z" lastmodified: "2025-11-27T14:38:31Z"
mac: ENC[AES256_GCM,data:qeBiuiK/On/NeMpjiCKeIvbQCRH0JcPFldJaTD+nHLtwNU+qpHX4y+dL/jTQrdSWxHV9+E3KmxnakEP91qZnycrSXhwSIIavNtXUP1veuv/JmHOxW6UxpJBJVDeMNe9k2AFQ3gwYEnXrisjvLDkYyqa+E+GsE7b82i3iyerpskY=,iv:jbw0OIJM3vr9SXkdAObc6JS6v4r11s6MPkg33x1sCvU=,tag:/BAMuCJgh78UgOXkTVkN7Q==,type:str] mac: ENC[AES256_GCM,data:PgNvIZeLRnGo6XYuzYsWhc/5pyKUpNQyXBwlgHk0F734lDlsX0ZPinekq35uDEn8NceWnh7Qi8ATZI/oFMsZn8EcB3SnMj8vzRH20Gm5bpESP2nu5Wxki/m0Eq+6afHFTc0k7dPnbvyQcL0MbUiA+nrembqHWRWo8lmrATWZrSc=,iv:Suf3RdzzeXTVebR4cSvhFCO2kWJV+ZECHy+REMa3KAs=,tag:2LSxZDge/aRMzzMcqWULOg==,type:str]
pgp: pgp:
- created_at: "2025-06-13T21:18:31Z" - created_at: "2025-06-13T21:18:31Z"
enc: |- enc: |-
@ -60,4 +64,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 4BE7925262289B476DBBC17B76FD3810215AE097 fp: 4BE7925262289B476DBBC17B76FD3810215AE097
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.11.0