Compare commits

...

10 Commits

17 changed files with 97 additions and 40 deletions

View File

@@ -2,20 +2,26 @@
{
services.ddclient = {
enable = true;
usev4 = "if, if=wan";
usev4 = "ifv4, ifv4=wan";
usev6 = "disabled";
protocol = "hetzner";
# server = "https://dns.hetzner.com/api/v1/";
username = "dominik.polakovics@cloonar.com";
passwordFile = config.sops.secrets.ddclient.path;
zone = "cloonar.com";
domains = [
"fw.cloonar.com"
"vpn.cloonar.com"
"git.cloonar.com"
"palworld.cloonar.com"
"matrix.cloonar.com"
"audiobooks.cloonar.com"
"element.cloonar.com"
"tinder.cloonar.com"
"foundry-vtt.cloonar.com"
"foundry-ha.cloonar.com"
"fw.cloonar.com"
"git.cloonar.com"
"jellyfin.cloonar.com"
"matrix.cloonar.com"
"palworld.cloonar.com"
"support.cloonar.com"
"sync.cloonar.com"
"vpn.cloonar.com"
];
};

View File

@@ -137,6 +137,7 @@
# multimedia
"/dl.cloonar.com/${config.networkPrefix}.97.5"
"/jellyfin.cloonar.com/${config.networkPrefix}.97.5"
"/audiobooks.cloonar.com/${config.networkPrefix}.97.5"
"/deconz.cloonar.multimedia/${config.networkPrefix}.97.22"

View File

@@ -2,6 +2,7 @@ let
devices = [
"device_tracker.dominiks_iphone"
"device_tracker.dominiks_mp01"
"device_tracker.dominiks_fairphone_6"
];
in {
services.home-assistant.extraComponents = [

View File

@@ -57,15 +57,6 @@
enableACME = true;
acmeRoot = null;
# Restrict to internal LAN only
extraConfig = ''
allow ${config.networkPrefix}.96.0/24;
allow ${config.networkPrefix}.97.0/24;
allow ${config.networkPrefix}.98.0/24;
allow ${config.networkPrefix}.99.0/24;
deny all;
'';
locations."/" = {
proxyPass = "http://${config.networkPrefix}.97.11:8096";
proxyWebsockets = true;
@@ -82,4 +73,25 @@
'';
};
};
services.nginx.virtualHosts."audiobooks.cloonar.com" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
locations."/" = {
proxyPass = "http://${config.networkPrefix}.97.11:13378";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering for better streaming performance
proxy_buffering off;
'';
};
};
}

View File

@@ -29,6 +29,10 @@
publicKey = "yv0AWQl4LFebVa7SvwdxpEmB3PPglwjoKy6A3og93WI=";
allowedIPs = [ "${config.networkPrefix}.98.204/32" ];
}
{ # FairPhone
publicKey = "tLsvuXo6Cp8tzjJau1yJZ9apeQvYa+cGrnAXBBifO3Y=";
allowedIPs = [ "${config.networkPrefix}.98.205/32" ];
}
];
};
wg_epicenter = {

View File

@@ -17,6 +17,7 @@ in {
./modules/cyberghost.nix
./modules/pyload.nix
./modules/jellyfin.nix
./modules/audiobookshelf.nix
./modules/power-management.nix
./modules/disk-monitoring.nix
./modules/ugreen-leds.nix
@@ -64,6 +65,7 @@ in {
directories = [
"/var/lib/pyload"
"/var/lib/jellyfin"
"/var/lib/audiobookshelf"
"/var/log"
"/var/lib/nixos"
"/var/bento"

View File

@@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }: {
# Audiobookshelf user with jellyfin and pyload groups for multimedia access
users.users.audiobookshelf = {
isSystemUser = true;
group = "audiobookshelf";
extraGroups = [ "jellyfin" "pyload" ];
};
users.groups.audiobookshelf = {};
services.audiobookshelf = {
enable = true;
openFirewall = true; # Opens default port 13378
host = "0.0.0.0"; # Listen on all interfaces
port = 13378;
};
}

View File

@@ -7,8 +7,6 @@
let
# Disk identifiers from hardware-configuration.nix
disks = [
"/dev/disk/by-id/ata-ST18000NM000J-2TV103_ZR52TBSB"
"/dev/disk/by-id/ata-ST18000NM000J-2TV103_ZR52V9QX"
"/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_8582A01SF4MJ"
"/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_75V2A0H3F4MJ"
"/dev/disk/by-id/nvme-KIOXIA-EXCERIA_PLUS_G3_SSD_7FJKS1MAZ0E7"

View File

@@ -52,6 +52,7 @@ in
home = "/var/lib/pyload";
createHome = true;
extraGroups = [ "jellyfin" ];
shell = pkgs.bashInteractive; # Required for filebot-process script
};
users.groups.pyload = {};

View File

@@ -42,7 +42,7 @@ local config = {
{ vim.o.shell, "<M-1>", "Float Terminal 1", "float", nil },
{ vim.o.shell, "<M-2>", "Float Terminal 2", "float", nil },
{ "claude", "<M-3>", "Claude Terminal", "float", nil },
{ vim.o.shell, "<M-4>", "Float Terminal 4", "float", nil },
{ "codex", "<M-4>", "Codex Terminal", "float", nil },
{ vim.o.shell, "<M-5>", "Float Terminal 5", "float", nil },
},
}

View File

@@ -20,7 +20,7 @@ let
"calendar.ui.version" = 3;
"calendar.timezone.local" = "Europe/Vienna";
"calendar.week.start" = 1;
"layout.css.devPixelsPerPx" = "1.25";
"layout.css.devPixelsPerPx" = "-1.0";
};
# Base calendar settings (without identity)
@@ -89,7 +89,7 @@ let
"signon.rememberSignons" = false;
"identity.sync.tokenserver.uri" = "https://sync.cloonar.com/1.0/sync/1.5";
# "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"layout.css.devPixelsPerPx" = "1.25";
"layout.css.devPixelsPerPx" = "-1.0"; # auto-detect from Wayland compositor
"media.ffmpeg.vaapi.enabled" = true;
"media.ffmpeg.vaapi-drm-display.enabled" = true;
"gfx.webrender.all" = true;

View File

@@ -5,6 +5,21 @@ let
system = pkgs.system;
};
in {
# Redis for Authelia session persistence
services.redis.servers.authelia = {
enable = true;
user = "authelia-main";
unixSocket = "/run/redis-authelia/redis.sock";
unixSocketPerm = 660;
settings = {
appendonly = "yes"; # Enable AOF persistence
appendfsync = "everysec"; # Sync every second
};
};
# Add authelia user to redis group for socket access
users.users.authelia-main.extraGroups = [ "redis-authelia" ];
sops.secrets.authelia-jwt-secret = {
owner = "authelia-main";
};
@@ -106,6 +121,9 @@ in {
inactivity = "45m";
remember_me_duration = "1M";
domain = "cloonar.com";
redis = {
host = "/run/redis-authelia/redis.sock";
};
# todo: enable with 4.38
# cookies = [
# {

View File

@@ -12,7 +12,7 @@
datasourceUid = "vm-datasource-uid";
relativeTimeRange = { from = 300; to = 0; };
model = {
expr = ''mdadm_array_state == 0'';
expr = ''mdadm_array_state < 1'';
instant = false;
};
}
@@ -35,7 +35,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "RAID array {{ $labels.array }} is degraded";
@@ -84,7 +84,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "RAID array {{ $labels.array }} has missing devices";

View File

@@ -12,7 +12,7 @@
datasourceUid = "vm-datasource-uid";
relativeTimeRange = { from = 300; to = 0; };
model = {
expr = ''smart_health_passed == 0'';
expr = ''smart_health_passed < 1'';
instant = false;
};
}
@@ -35,7 +35,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "S.M.A.R.T. health check FAILED on {{ $labels.device }}";
@@ -84,7 +84,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "Reallocated sectors detected on {{ $labels.device }}";
@@ -133,7 +133,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "Pending sectors detected on {{ $labels.device }}";
@@ -182,7 +182,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "Offline uncorrectable errors on {{ $labels.device }}";
@@ -231,7 +231,7 @@
}
];
for = "10m";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "High temperature on {{ $labels.device }}";
@@ -280,7 +280,7 @@
}
];
for = "0s";
noDataState = "NoData";
noDataState = "OK";
execErrState = "Error";
annotations = {
summary = "UDMA CRC errors on {{ $labels.device }}";

View File

@@ -115,7 +115,6 @@ in
settings = {
apiToken = "\${PUSHOVER_API_TOKEN}";
userKey = "\${PUSHOVER_USER_KEY}";
device = "iphone";
priority = 2;
retry = "30s";
expire = "2m";
@@ -134,7 +133,6 @@ in
settings = {
apiToken = "\${PUSHOVER_API_TOKEN}";
userKey = "\${PUSHOVER_USER_KEY}";
device = "iphone";
priority = 1;
sound = "siren";
okSound = "magic";

View File

@@ -1,11 +1,11 @@
{ lib, pkgs, runCommand, claude-code }:
let
version = "2.0.76";
version = "2.1.12";
src = pkgs.fetchzip {
url = "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-${version}.tgz";
hash = "sha256-46IqiGJZrZM4vVcanZj/vY4uxFH3/4LxNA+Qb6iIHDk=";
hash = "sha256-JX72YEM2fXY7qKVkuk+UFeef0OhBffljpFBjIECHMXw=";
};
# Create a modified source with our package-lock.json
@@ -22,7 +22,7 @@ in
npmDeps = pkgs.fetchNpmDeps {
src = srcWithLock;
hash = "sha256-xSNyYImDpsW6AltA7d0ayMsfVaBcnyPIQOg/Ea2cGNk=";
hash = "sha256-iJwtwAYb/+1Une6Tjxek5ccf4ui3tYWy4kNlHES9He4=";
};
# Remove the old postPatch since srcWithLock already includes package-lock.json

View File

@@ -5,13 +5,13 @@
"packages": {
"": {
"dependencies": {
"@anthropic-ai/claude-code": "^2.0.76"
"@anthropic-ai/claude-code": "^2.1.12"
}
},
"node_modules/@anthropic-ai/claude-code": {
"version": "2.0.76",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-2.0.76.tgz",
"integrity": "sha512-BVwPez7Pst729gxHZNb7iUdjrn4UAzO49zC+Bxlyf0fMe3SsutxEhKTT16VMs2qInE9xhEBCxajCCa888mFPBg==",
"version": "2.1.12",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-2.1.12.tgz",
"integrity": "sha512-oJlbUJc6iyuTA6X1z+Wsli4cYWqSHT9Ttc/jBXArrrBQcILPLb5lBOKfbVJJgcH3bNLxsXwnAkZjtmmM5SqtsQ==",
"license": "SEE LICENSE IN README.md",
"bin": {
"claude": "cli.js"