refactor!: switch to dendritic pattern

BREAKING CHANGE: complete reorganization of the repository
This commit is contained in:
2026-09-30 18:36:06 +02:00
parent 12684b4e9c
commit 5f4a7a4a42
323 changed files with 7117 additions and 7380 deletions
+40
View File
@@ -0,0 +1,40 @@
{
flake.modules.nixos.calibre = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.calibre;
in {
options.mySystem.services.calibre = {
enable = mkEnableOption "Enable Calibre Web";
user = mkOption {
type = types.str;
default = "phundrak";
};
group = mkOption {
type = types.str;
default = "users";
};
dataDir = mkOption {
type = types.str;
example = "/tank/calibre/conf";
default = "/tank/calibre/conf";
};
library = mkOption {
type = types.str;
example = "/tank/calibre/library";
default = "/tank/calibre/library";
};
};
config.services.calibre-web = mkIf cfg.enable {
inherit (cfg) enable user dataDir group;
options = {
calibreLibrary = cfg.library;
enableBookConversion = true;
enableBookUploading = true;
};
};
};
}
+61
View File
@@ -0,0 +1,61 @@
{
flake.modules.nixos.docker = {
lib,
config,
pkgs,
...
}:
with lib; let
cfg = config.mySystem.dev.docker;
containerGroups = ["docker"] ++ lists.optional cfg.podman.enable "podman";
in {
options.mySystem.dev.docker = {
enable = mkEnableOption "Enable Docker";
podman.enable = mkEnableOption "Enable Podman rather than Docker";
nvidia.enable = mkEnableOption "Activate Nvidia support";
autoprune.enable = mkEnableOption "Enable autoprune";
storage = mkOption {
type = types.nullOr types.path;
default = null;
example = "/path/to/docker/storage";
};
};
config = mkIf cfg.enable {
users.users = {
phundrak = mkIf config.mySystem.users.phundrak.enable {
extraGroups = containerGroups;
};
creug = mkIf config.mySystem.users.creug.enable {
extraGroups = containerGroups;
};
};
environment.systemPackages = with pkgs;
[
dive # A tool for exploring each layer in a docker image
grype # Vulnerability scanner for container images and filesystems
]
++ lists.optionals cfg.podman.enable [
podman-compose
podman-desktop
];
virtualisation = {
docker = mkIf (!cfg.podman.enable) {
enable = true;
enableNvidia = cfg.nvidia.enable;
autoPrune.enable = cfg.autoprune.enable;
daemon.settings = mkIf (cfg.storage != null) {
"data-root" = cfg.storage;
};
};
podman = mkIf cfg.podman.enable {
enable = true;
dockerCompat = cfg.enable;
enableNvidia = cfg.nvidia.enable;
dockerSocket.enable = cfg.enable;
autoPrune.enable = cfg.autoprune.enable;
};
};
};
};
}
+23
View File
@@ -0,0 +1,23 @@
{
flake.modules.nixos.endlessh = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.endlessh;
in {
options.mySystem.services.endlessh = {
enable = mkEnableOption "Enables endlessh.";
port = mkOption {
type = types.port;
default = 2222;
example = 22;
};
};
config.services.endlessh-go = mkIf cfg.enable {
inherit (cfg) enable port;
openFirewall = true;
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{
flake.modules.nixos.fwupd = {
lib,
config,
...
}:
with lib; let
cfg = config.mySystem.services.fwupd;
in {
options.mySystem.services.fwupd.enable = mkEnableOption "Enable fwupd";
config.services.fwupd = mkIf cfg.enable {
inherit (cfg) enable;
};
};
}
+38
View File
@@ -0,0 +1,38 @@
{
flake.modules.nixos.harmonia = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.harmonia;
in {
options.mySystem.services.harmonia = {
enable = mkEnableOption "Harmonia Nix binary cache server";
port = mkOption {
type = types.port;
default = 5000;
description = "Port to listen on";
};
priority = mkOption {
type = types.ints.between 0 100;
default = 50;
description = "Cache priority (lower = higher priority, 0-100)";
};
signKeyPaths = mkOption {
type = types.listOf types.path;
description = "Paths to the signing keys to use for signing the cache.";
};
};
config = mkIf cfg.enable {
services.harmonia.cache = {
enable = true;
inherit (cfg) signKeyPaths;
settings = {
inherit (cfg) priority;
bind = "[::]:${toString cfg.port}";
};
};
};
};
}
+30
View File
@@ -0,0 +1,30 @@
{
flake.modules.nixos.jellyfin = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.jellyfin;
in {
options.mySystem.services.jellyfin = {
enable = mkEnableOption "Enable Jellyfin";
dataDir = mkOption {
type = types.str;
default = "/tank/jellyfin/data";
example = "/tank/jellyfin/data";
};
user = mkOption {
type = types.str;
default = "phundrak";
};
group = mkOption {
type = types.str;
default = "users";
};
};
config.services.jellyfin = mkIf cfg.enable {
inherit (cfg) enable group user dataDir;
};
};
}
+22
View File
@@ -0,0 +1,22 @@
{
flake.modules.nixos.languagetool = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.languagetool;
in {
options.mySystem.services.languagetool = {
enable = mkEnableOption "Enables languagetool";
port = mkOption {
type = types.port;
default = 8081;
example = 80;
};
};
config.services.languagetool = mkIf cfg.enable {
inherit (cfg) enable port;
};
};
}
+37
View File
@@ -0,0 +1,37 @@
{
flake.modules.nixos.plex = {
lib,
config,
...
}:
with lib; let
cfg = config.mySystem.services.plex;
in {
options.mySystem.services.plex = {
enable = mkEnableOption "Enable Plex";
group = mkOption {
type = types.str;
default = "users";
example = "users";
description = "Group under which Plex runs";
};
dataDir = mkOption {
type = types.str;
example = "/tank/plex-config";
};
user = mkOption {
type = types.str;
default = "phundrak";
};
};
config = {
services.plex = mkIf cfg.enable {
inherit (cfg) enable user group dataDir;
openFirewall = cfg.enable;
};
boot.kernel.sysctl = {
"kernel.unprivileged_userns_clone" = 1;
};
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{
flake.modules.nixos.printing = {
lib,
config,
...
}:
with lib; let
cfg = config.mySystem.services.printing;
in {
options.mySystem.services.printing.enable = mkEnableOption "Enable printing with CUPS";
config.services.printing = mkIf cfg.enable {
inherit (cfg) enable;
};
};
}
+37
View File
@@ -0,0 +1,37 @@
{
flake.modules.nixos.ssh = {
lib,
config,
...
}:
with lib; let
cfg = config.mySystem.services.ssh;
in {
options.mySystem.services.ssh = {
enable = mkEnableOption "Enables OpenSSH";
allowedUsers = mkOption {
type = types.listOf types.str;
example = ["alice" "bob"];
default = ["phundrak"];
};
passwordAuthentication = mkOption {
type = types.bool;
example = true;
default = false;
};
port = mkOption {
type = types.int;
default = 22;
};
};
config.services.openssh = mkIf cfg.enable {
inherit (cfg) enable;
ports = [cfg.port];
settings = {
AllowUsers = cfg.allowedUsers;
PermitRootLogin = "no";
PasswordAuthentication = cfg.passwordAuthentication;
};
};
};
}
+71
View File
@@ -0,0 +1,71 @@
{
flake.modules.nixos.sunshine = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.sunshine;
in {
options.mySystem.services.sunshine = {
enable = mkEnableOption "Enables Sunshine";
autostart = mkEnableOption "Enables autostart";
};
config.services.sunshine = mkIf cfg.enable {
inherit (cfg) enable;
autoStart = cfg.autostart;
capSysAdmin = true;
openFirewall = true;
settings = {
sunshine_name = config.mySystem.networking.hostname;
locale = "en_GB";
system_tray = "enabled";
output_name = 1;
csrf_allowed_origins = "192.168.1.86,marpa,localhost";
};
applications.apps = let
defaultPrep = [
{
do = "sh -c \"hyprctl -i 0 keyword monitor \\\"DP-2,\${SUNSHINE_CLIENT_WIDTH}x\${SUNSHINE_CLIENT_HEIGHT}@\${SUNSHINE_CLIENT_FPS},0x0,1\\\"\"";
undo = "sh -c \"hyprctl -i 0 keyword monitor 'DP-2,2560x1080@60,0x0,1,transform,1'\"";
}
];
in [
{
name = "Desktop";
image-path = "desktop.png";
prep-cmd = defaultPrep;
}
{
name = "Low Res Desktop";
image-path = "desktop.png";
prep-cmd = defaultPrep;
}
{
name = "Steam Big Picture";
detached = ["setsid steam steam://open/bigpicture"];
prep-cmd = defaultPrep;
image-path = "steam.png";
}
{
name = "OpenTTD";
cmd = "openttd";
image-path = "/home/phundrak/.config/sunshine/covers/igdb_18074.png";
prep-cmd = defaultPrep;
}
{
name = "OpenMW";
cmd = "openmw";
image-path = "/home/phundrak/.config/sunshine/covers/igdb_24775.png";
prep-cmd = defaultPrep;
}
{
name = "Vintage Story";
cmd = "flatpak run at.vintagestory.VintageStory";
image-path = "/home/phundrak/.config/sunshine/covers/igdb_69547.png";
prep-cmd = defaultPrep;
}
];
};
};
}
+73
View File
@@ -0,0 +1,73 @@
{
flake.modules.nixos.traefik = {
config,
lib,
...
}:
with lib; let
cfg = config.mySystem.services.traefik;
in {
options.mySystem.services.traefik = {
enable = mkEnableOption "Enable Traefik";
email = mkOption {
type = types.str;
default = "";
};
dataDir = mkOption {
type = types.path;
default = "/tank/traefik";
example = "/path/to/traefik/data";
};
environmentFiles = mkOption {
type = types.listOf types.path;
example = ["/var/traefik/traefik.env"];
default = [];
};
dynamicConfigFile = mkOption {
type = types.path;
default = "${cfg.dataDir}/traefik.yaml";
example = "/var/traefik/dynamic.yaml";
};
};
config.services.traefik = {
inherit (cfg) enable dynamicConfigFile environmentFiles;
staticConfigOptions = {
api.dashboard = true;
log = {
level = "INFO";
filePath = "${cfg.dataDir}/traefik.log";
format = "json";
};
accessLog.filePath = "${cfg.dataDir}/access.log";
entryPoints = {
web = {
address = ":80";
asDefault = true;
http.redirections.entrypoint = {
to = "websecure";
scheme = "https";
};
};
websecure = {
address = ":443";
asDefault = true;
httpChallenge.entryPoint = "websecure";
};
};
providers.docker = {
endpoint = "unix:///var/run/docker.sock";
exposedByDefault = false;
};
certificatesResolvers.cloudflare.acme = {
inherit (cfg) email;
storage = "${cfg.dataDir}/acme.json";
dnsChallenge = {
provider = "cloudflare";
resolvers = ["1.1.1.1:53" "1.0.0.1:53"];
propagation.delayBeforeChecks = 60;
};
};
};
};
};
}