This commit is contained in:
mjallen18
2026-03-16 16:41:46 -05:00
parent 742e1703d8
commit 7538f734f1
19 changed files with 259 additions and 851 deletions

215
flake.lock generated
View File

@@ -24,7 +24,9 @@
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"napalm": "napalm", "napalm": "napalm",
"nixpkgs": "nixpkgs", "nixpkgs": [
"nixpkgs"
],
"pyproject-build-systems": "pyproject-build-systems", "pyproject-build-systems": "pyproject-build-systems",
"pyproject-nix": "pyproject-nix", "pyproject-nix": "pyproject-nix",
"systems": "systems", "systems": "systems",
@@ -181,7 +183,9 @@
"cosmic": { "cosmic": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_2",
"nixpkgs": "nixpkgs_2", "nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable", "nixpkgs-stable": "nixpkgs-stable",
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
@@ -216,7 +220,7 @@
}, },
"darwin": { "darwin": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1773000227, "lastModified": 1773000227,
@@ -444,7 +448,7 @@
}, },
"flake-utils-plus": { "flake-utils-plus": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_3" "flake-utils": "flake-utils_2"
}, },
"locked": { "locked": {
"lastModified": 1738591040, "lastModified": 1738591040,
@@ -465,24 +469,6 @@
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": { "locked": {
"lastModified": 1694529238, "lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
@@ -659,7 +645,7 @@
}, },
"home-manager_3": { "home-manager_3": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_7" "nixpkgs": "nixpkgs_5"
}, },
"locked": { "locked": {
"lastModified": 1760295538, "lastModified": 1760295538,
@@ -709,7 +695,7 @@
"impermanence": { "impermanence": {
"inputs": { "inputs": {
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_2"
}, },
"locked": { "locked": {
"lastModified": 1769548169, "lastModified": 1769548169,
@@ -749,7 +735,7 @@
"lanzaboote": { "lanzaboote": {
"inputs": { "inputs": {
"crane": "crane", "crane": "crane",
"nixpkgs": "nixpkgs_5", "nixpkgs": "nixpkgs_3",
"pre-commit": "pre-commit", "pre-commit": "pre-commit",
"rust-overlay": "rust-overlay_2" "rust-overlay": "rust-overlay_2"
}, },
@@ -820,7 +806,7 @@
"cachyos-kernel-patches": "cachyos-kernel-patches", "cachyos-kernel-patches": "cachyos-kernel-patches",
"flake-compat": "flake-compat_4", "flake-compat": "flake-compat_4",
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_6" "nixpkgs": "nixpkgs_4"
}, },
"locked": { "locked": {
"lastModified": 1773339151, "lastModified": 1773339151,
@@ -900,7 +886,7 @@
"nix-plist-manager": { "nix-plist-manager": {
"inputs": { "inputs": {
"home-manager": "home-manager_3", "home-manager": "home-manager_3",
"nixpkgs": "nixpkgs_8" "nixpkgs": "nixpkgs_6"
}, },
"locked": { "locked": {
"lastModified": 1765533928, "lastModified": 1765533928,
@@ -938,7 +924,7 @@
}, },
"nix-vscode-extensions": { "nix-vscode-extensions": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_9" "nixpkgs": "nixpkgs_7"
}, },
"locked": { "locked": {
"lastModified": 1773369788, "lastModified": 1773369788,
@@ -954,29 +940,10 @@
"type": "github" "type": "github"
} }
}, },
"nixai": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_10"
},
"locked": {
"lastModified": 1755942173,
"narHash": "sha256-wSjUhxwartHibNyGrVudc0Zmsv/qgUTL6rBeETl4UTE=",
"owner": "olafkfreund",
"repo": "nix-ai-help",
"rev": "056c3ddc1601b1a8c4d6b1d5cf0ba2d35b8206ee",
"type": "github"
},
"original": {
"owner": "olafkfreund",
"repo": "nix-ai-help",
"type": "github"
}
},
"nixos-apple-silicon": { "nixos-apple-silicon": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_5", "flake-compat": "flake-compat_5",
"nixpkgs": "nixpkgs_11" "nixpkgs": "nixpkgs_8"
}, },
"locked": { "locked": {
"lastModified": 1772952158, "lastModified": 1772952158,
@@ -1010,16 +977,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1771848320, "lastModified": 1765934234,
"narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", "narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2fc6539b481e1d2569f25f8799236694180c0993", "rev": "af84f9d270d404c17699522fab95bbf928a2d92f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixpkgs-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -1119,54 +1086,6 @@
} }
}, },
"nixpkgs_10": { "nixpkgs_10": {
"locked": {
"lastModified": 1751271578,
"narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_11": {
"locked": {
"lastModified": 1768305791,
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_12": {
"locked": {
"lastModified": 1773389992,
"narHash": "sha256-wvfdLLWJ2I9oEpDd9PfMA8osfIZicoQ5MT1jIwNs9Tk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c06b4ae3d6599a672a6210b7021d699c351eebda",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_13": {
"locked": { "locked": {
"lastModified": 1772736753, "lastModified": 1772736753,
"narHash": "sha256-au/m3+EuBLoSzWUCb64a/MZq6QUtOV8oC0D9tY2scPQ=", "narHash": "sha256-au/m3+EuBLoSzWUCb64a/MZq6QUtOV8oC0D9tY2scPQ=",
@@ -1183,38 +1102,6 @@
} }
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": {
"lastModified": 1751011381,
"narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1765934234,
"narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "af84f9d270d404c17699522fab95bbf928a2d92f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1768564909, "lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
@@ -1230,7 +1117,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_5": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1764950072, "lastModified": 1764950072,
"narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=", "narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=",
@@ -1246,7 +1133,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_6": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1773276312, "lastModified": 1773276312,
"narHash": "sha256-UujcRqoPEyi0Bd77+cqfAxa4aq0SoKOYTcJNWn+0ZvM=", "narHash": "sha256-UujcRqoPEyi0Bd77+cqfAxa4aq0SoKOYTcJNWn+0ZvM=",
@@ -1262,7 +1149,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_7": { "nixpkgs_5": {
"locked": { "locked": {
"lastModified": 1759831965, "lastModified": 1759831965,
"narHash": "sha256-vgPm2xjOmKdZ0xKA6yLXPJpjOtQPHfaZDRtH+47XEBo=", "narHash": "sha256-vgPm2xjOmKdZ0xKA6yLXPJpjOtQPHfaZDRtH+47XEBo=",
@@ -1278,7 +1165,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_8": { "nixpkgs_6": {
"locked": { "locked": {
"lastModified": 1757068644, "lastModified": 1757068644,
"narHash": "sha256-NOrUtIhTkIIumj1E/Rsv1J37Yi3xGStISEo8tZm3KW4=", "narHash": "sha256-NOrUtIhTkIIumj1E/Rsv1J37Yi3xGStISEo8tZm3KW4=",
@@ -1294,7 +1181,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_9": { "nixpkgs_7": {
"locked": { "locked": {
"lastModified": 1766025857, "lastModified": 1766025857,
"narHash": "sha256-Lav5jJazCW4mdg1iHcROpuXqmM94BWJvabLFWaJVJp0=", "narHash": "sha256-Lav5jJazCW4mdg1iHcROpuXqmM94BWJvabLFWaJVJp0=",
@@ -1310,6 +1197,38 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_8": {
"locked": {
"lastModified": 1768305791,
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_9": {
"locked": {
"lastModified": 1773389992,
"narHash": "sha256-wvfdLLWJ2I9oEpDd9PfMA8osfIZicoQ5MT1jIwNs9Tk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c06b4ae3d6599a672a6210b7021d699c351eebda",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nur": { "nur": {
"inputs": { "inputs": {
"flake-parts": [ "flake-parts": [
@@ -1451,10 +1370,9 @@
"nix-plist-manager": "nix-plist-manager", "nix-plist-manager": "nix-plist-manager",
"nix-rosetta-builder": "nix-rosetta-builder", "nix-rosetta-builder": "nix-rosetta-builder",
"nix-vscode-extensions": "nix-vscode-extensions", "nix-vscode-extensions": "nix-vscode-extensions",
"nixai": "nixai",
"nixos-apple-silicon": "nixos-apple-silicon", "nixos-apple-silicon": "nixos-apple-silicon",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_12", "nixpkgs": "nixpkgs_9",
"nixpkgs-otbr": "nixpkgs-otbr", "nixpkgs-otbr": "nixpkgs-otbr",
"nixpkgs-stable": "nixpkgs-stable_2", "nixpkgs-stable": "nixpkgs-stable_2",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
@@ -1532,7 +1450,7 @@
}, },
"sops-nix": { "sops-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_13" "nixpkgs": "nixpkgs_10"
}, },
"locked": { "locked": {
"lastModified": 1773096132, "lastModified": 1773096132,
@@ -1584,7 +1502,7 @@
"nixpkgs" "nixpkgs"
], ],
"nur": "nur", "nur": "nur",
"systems": "systems_4", "systems": "systems_3",
"tinted-foot": "tinted-foot", "tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty", "tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes", "tinted-schemes": "tinted-schemes",
@@ -1650,21 +1568,6 @@
"type": "github" "type": "github"
} }
}, },
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"tinted-foot": { "tinted-foot": {
"flake": false, "flake": false,
"locked": { "locked": {

View File

@@ -3,6 +3,8 @@
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
# Fork required: openthread-border-router is not yet in nixpkgs-unstable.
# Used by modules/nixos/homeassistant/services/thread/default.nix
nixpkgs-otbr.url = "github:mrene/nixpkgs/openthread-border-router"; nixpkgs-otbr.url = "github:mrene/nixpkgs/openthread-border-router";
home-manager-stable = { home-manager-stable = {
@@ -19,7 +21,7 @@
home-manager = home-manager-unstable; home-manager = home-manager-unstable;
# The name "snowfall-lib" is required due to how Snowfall Lib processes your # The name "snowfall-lib" is required due to how Snowfall Lib processes your
# flake's inputs. # flake's inputs. Using a personal fork for custom changes.
snowfall-lib = { snowfall-lib = {
url = "github:mjallen18/snowfall-lib"; url = "github:mjallen18/snowfall-lib";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -46,17 +48,18 @@
inputs.home-manager.follows = "home-manager"; inputs.home-manager.follows = "home-manager";
}; };
cosmic.url = "github:lilyinstarlight/nixos-cosmic"; cosmic = {
url = "github:lilyinstarlight/nixos-cosmic";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
authentik-nix = { authentik-nix = {
url = "github:nix-community/authentik-nix"; url = "github:nix-community/authentik-nix";
# inputs.nixpkgs.follows = "nixpkgs-stable"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixai.url = "github:olafkfreund/nix-ai-help";
disko = { disko = {
# the fork is needed for partition attributes support # the fork is needed for partition attributes support
# url = "github:nvmd/disko/gpt-attrs"; # url = "github:nvmd/disko/gpt-attrs";
@@ -188,13 +191,13 @@
# NAS # # NAS #
# ###################################################### # ######################################################
jallen-nas = { jallen-nas = {
# home-manager is already in systems.modules.nixos above
modules = with inputs; [ modules = with inputs; [
nixos-hardware.nixosModules.common-pc nixos-hardware.nixosModules.common-pc
nixos-hardware.nixosModules.common-cpu-amd nixos-hardware.nixosModules.common-cpu-amd
nixos-hardware.nixosModules.common-cpu-amd-pstate nixos-hardware.nixosModules.common-cpu-amd-pstate
# nixos-hardware.nixosModules.common-cpu-amd-zenpower # nixos-hardware.nixosModules.common-cpu-amd-zenpower
nixos-hardware.nixosModules.common-hidpi nixos-hardware.nixosModules.common-hidpi
home-manager.nixosModules.home-manager
]; ];
}; };
@@ -202,8 +205,8 @@
# NUC # # NUC #
# ###################################################### # ######################################################
nuc-nixos = { nuc-nixos = {
# disko is already in systems.modules.nixos above
modules = with inputs; [ modules = with inputs; [
disko.nixosModules.disko
nixos-hardware.nixosModules.common-cpu-amd nixos-hardware.nixosModules.common-cpu-amd
nixos-hardware.nixosModules.common-cpu-amd-pstate nixos-hardware.nixosModules.common-cpu-amd-pstate
# nixos-hardware.nixosModules.common-cpu-amd-zenpower # nixos-hardware.nixosModules.common-cpu-amd-zenpower
@@ -217,9 +220,8 @@
# Pi5 # # Pi5 #
# ###################################################### # ######################################################
pi5 = { pi5 = {
modules = with inputs; [ # disko is already in systems.modules.nixos above
disko.nixosModules.disko modules = [ ];
];
}; };
# ###################################################### # ######################################################
@@ -278,13 +280,7 @@
outputs-builder = channels: { outputs-builder = channels: {
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix; formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
# mjallen-lib overlay is auto-discovered from overlays/mjallen-lib/default.nix
# Add mjallen-lib to the flake outputs
overlays = {
mjallen-lib = _final: _prev: {
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
};
};
}; };
}; };
} }

View File

@@ -1,4 +1,9 @@
{ pkgs, namespace, ... }: {
pkgs,
config,
namespace,
...
}:
{ {
home = { home = {
username = "admin"; username = "admin";
@@ -25,6 +30,10 @@
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml"; defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
validateSopsFiles = false; validateSopsFiles = false;
secrets = { secrets = {
# NOTE: add the following key to secrets/secrets.yaml via `sops secrets/secrets.yaml`
# before deploying: hass-mcp/token: <your HA long-lived access token>
"hass-mcp/token" = { };
"ssh-keys-public/jallen-nas" = { "ssh-keys-public/jallen-nas" = {
path = "/home/admin/.ssh/id_ed25519.pub"; path = "/home/admin/.ssh/id_ed25519.pub";
mode = "0644"; mode = "0644";
@@ -53,6 +62,15 @@
mode = "0600"; mode = "0600";
}; };
}; };
templates."hass-mcp.env" = {
path = "/home/admin/.config/sops/hass-mcp.env";
mode = "0600";
content = ''
HA_URL=http://nuc-nixos.local:8123
HA_TOKEN=${config.sops.placeholder."hass-mcp/token"}
'';
};
}; };
programs = { programs = {
@@ -155,12 +173,13 @@
]; ];
}; };
hass-mcp = { hass-mcp = {
command = "uvx"; # Token is read at runtime from a sops-rendered env file.
args = [ "hass-mcp" ]; # The wrapper script sources ~/.config/sops/hass-mcp.env before launching uvx.
env = { command = "bash";
HA_URL = "http://nuc-nixos.local:8123"; args = [
HA_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1ZDM2MTliNWNjMGY0ZGI2OWQzOTQ4Mjk0ZDFmNjAxMCIsImlhdCI6MTc3MDc2MjA1NywiZXhwIjoyMDg2MTIyMDU3fQ.P52jeX8GQcdGdzpbU3NCWZMUjkJZHFnOeR8--jy9dF8"; "-c"
}; "set -a; source ${"\${HOME}"}/.config/sops/hass-mcp.env; set +a; exec uvx hass-mcp"
];
}; };
mcp-server-code-runner = { mcp-server-code-runner = {
command = "npm"; command = "npm";

View File

@@ -40,18 +40,25 @@ rec {
let let
cfg = config.${namespace}.${domain}.${name}; cfg = config.${namespace}.${domain}.${name};
# Create reverse proxy configuration using mkReverseProxy upstreamUrl =
reverseProxyConfig = lib.${namespace}.mkReverseProxy { if cfg.reverseProxy.upstreamUrl != null then
inherit name; cfg.reverseProxy.upstreamUrl
subdomain = cfg.reverseProxy.subdomain; else
url = "http://${config.${namespace}.network.ipv4.address}:${toString cfg.port}"; "http://127.0.0.1:${toString cfg.port}";
middlewares = cfg.reverseProxy.middlewares;
}; fqdn = "${cfg.reverseProxy.subdomain}.${cfg.reverseProxy.domain}";
defaultConfig = { defaultConfig = {
${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable { # Caddy reverse proxy: when reverseProxy.enable = true, contribute this
reverseProxies = [ reverseProxyConfig ]; # service's virtual host block to the Caddy config. The TLS wildcard
}; # cert is handled via a (cloudflare_tls) snippet defined in globalConfig.
# services.caddy.virtualHosts.${fqdn} = lib.mkIf cfg.reverseProxy.enable {
# extraConfig = ''
# import cloudflare_tls
# reverse_proxy ${upstreamUrl}
# ${cfg.reverseProxy.extraCaddyConfig}
# '';
# };
# Open firewall # Open firewall
networking.firewall = lib.mkIf cfg.openFirewall { networking.firewall = lib.mkIf cfg.openFirewall {
@@ -222,14 +229,20 @@ rec {
mkBoolOpt' = mkOpt' types.bool; mkBoolOpt' = mkOpt' types.bool;
mkReverseProxyOpt = name: { mkReverseProxyOpt = name: {
enable = mkBoolOpt false "Enable reverse proxy support"; enable = mkBoolOpt false "Enable Caddy reverse proxy for this service";
subdomain = mkOpt types.str name "subdomain of the service"; subdomain = mkOpt types.str name "Subdomain for the service (default: service name)";
middlewares = mkOpt (types.listOf types.str) [ domain = mkOpt types.str "mjallen.dev" "Base domain for the reverse proxy";
"crowdsec"
"whitelist-geoblock" # Override the upstream URL if the backend is not on localhost at cfg.port.
] "List of middlewares to use"; # Leave empty to use http://127.0.0.1:<port> automatically.
upstreamUrl =
mkOpt (types.nullOr types.str) null
"Override upstream URL (e.g. for services on a different host). Defaults to http://127.0.0.1:<port>.";
# Extra Caddyfile directives inserted inside the virtual host block.
extraCaddyConfig = mkOpt types.lines "" "Extra Caddyfile directives for this virtual host block";
}; };
# Standard enable/disable patterns # Standard enable/disable patterns

View File

@@ -31,7 +31,7 @@ in
}; };
fullName = mkOption { fullName = mkOption {
type = types.str; type = types.str;
default = "Austin Horstman"; default = "Matt Jallen";
description = "The full name of the user."; description = "The full name of the user.";
}; };
home = mkOption { home = mkOption {
@@ -41,8 +41,8 @@ in
}; };
icon = mkOption { icon = mkOption {
type = (types.nullOr types.package); type = (types.nullOr types.package);
default = pkgs.${namespace}.user-icon; default = null;
description = "The profile picture to use for the user."; description = "The profile picture to use for the user. Set to a package whose output is the icon file (e.g. a derivation producing a PNG).";
}; };
name = mkOption { name = mkOption {
type = (types.nullOr types.str); type = (types.nullOr types.str);
@@ -145,7 +145,7 @@ in
myip = "${getExe pkgs.curl} ifconfig.me"; myip = "${getExe pkgs.curl} ifconfig.me";
# Cryptography # Cryptography
genpass = "${getExe pkgs.openssl} rand - base64 20"; # Generate a random, 20-character password genpass = "${getExe pkgs.openssl} rand -base64 20"; # Generate a random, 20-character password
sha = "shasum -a 256"; # Test checksum sha = "shasum -a 256"; # Test checksum
}; };

View File

@@ -1,12 +1,21 @@
{ {
config, config,
lib, lib,
pkgs,
namespace, namespace,
... ...
}: }:
with lib; with lib;
let let
cfg = config.${namespace}.services.home-assistant; cfg = config.${namespace}.services.home-assistant;
# ESPHome with littlefs-python added to PYTHONPATH so PlatformIO's
# espressif32 platform builder can import it (needed for LittleFS support).
esphomeWithLittlefs = pkgs.esphome.overridePythonAttrs (oldAttrs: {
makeWrapperArgs = (oldAttrs.makeWrapperArgs or [ ]) ++ [
"--prefix PYTHONPATH : ${pkgs.${namespace}.littlefs-python}/${pkgs.python3.sitePackages}"
];
});
in in
{ {
config = mkIf cfg.enable { config = mkIf cfg.enable {
@@ -15,6 +24,17 @@ in
enable = true; enable = true;
openFirewall = true; # 6052 openFirewall = true; # 6052
address = "0.0.0.0"; address = "0.0.0.0";
package = esphomeWithLittlefs;
};
};
# Add uv to the ESPHome service PATH so PlatformIO uses the Nix-provided
# binary instead of downloading its own (which would fail due to permissions).
# Also disable MemoryDenyWriteExecute so uv (a native Rust binary) can run.
systemd.services.esphome = {
path = [ pkgs.uv ];
serviceConfig = {
MemoryDenyWriteExecute = lib.mkForce false;
}; };
}; };
}; };

View File

@@ -5,6 +5,9 @@
... ...
}: }:
with lib; with lib;
# NOTE: AUTHENTIK_TOKEN for the RAC outpost is stored in sops.
# Add jallen-nas/authentik-rac/token to secrets/nas-secrets.yaml and ensure
# jallen-nas/sops.nix declares the "authentik-rac.env" template before deploying.
let let
name = "authentik"; name = "authentik";
cfg = config.${namespace}.services.${name}; cfg = config.${namespace}.services.${name};
@@ -41,10 +44,12 @@ let
volumes = [ volumes = [
"${cfg.configDir}/authentik-rac:/media" "${cfg.configDir}/authentik-rac:/media"
]; ];
# AUTHENTIK_TOKEN is injected via the sops template "authentik-rac.env"
# defined in systems/x86_64-linux/jallen-nas/sops.nix
environmentFiles = [ config.sops.templates."authentik-rac.env".path ];
environment = { environment = {
AUTHENTIK_HOST = "https://${name}.mjallen.dev"; AUTHENTIK_HOST = "https://${name}.mjallen.dev";
AUTHENTIK_TOKEN = "0XGkB2pXoOTqcCMAjucAtfamvlsIZCPmy1Zri54Ozjj3zzMCvcLwkQPrukfx"; AUTHENTIK_INSECURE = "false";
AUTHENTIK_INSECURE = "false"; # Set to true for self-signed certs
PUID = toString cfg.puid; PUID = toString cfg.puid;
PGID = toString cfg.pgid; PGID = toString cfg.pgid;
TZ = cfg.timeZone; TZ = cfg.timeZone;

View File

@@ -1,369 +0,0 @@
{
config,
lib,
namespace,
...
}:
with lib;
let
cfg = config.${namespace}.services.traefik;
# Process reverseProxies into service and router configurations
reverseProxyServiceConfigs =
let
makeService = reverseProxy: nameValuePair reverseProxy.service.name reverseProxy.service.config;
in
listToAttrs (map makeService cfg.reverseProxies);
reverseProxyRouterConfigs =
let
makeRouter = reverseProxy: nameValuePair reverseProxy.router.subdomain reverseProxy.router.config;
in
listToAttrs (map makeRouter cfg.reverseProxies);
domain = "mjallen.dev";
# Forward services
authUrl = "http://localhost:9000/outpost.goauthentik.io";
cacheUrl = "http://localhost:9012";
hassUrl = "http://nuc-nixos.local:8123";
# Plugins
traefikPlugins = {
bouncer = {
moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin";
version = "v1.4.5";
};
geoblock = {
moduleName = "github.com/PascalMinder/geoblock";
version = "v0.2.5";
};
};
# Ports
httpPort = 80;
httpsPort = 443;
traefikPort = 8080;
metricsPort = 8082;
forwardPorts = [
httpPort
httpsPort
traefikPort
metricsPort
];
# misc
letsEncryptEmail = "jalle008@proton.me";
configDir = "/media/nas/main/appdata";
in
{
imports = [
./options.nix
./sops.nix
];
config = mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = forwardPorts;
allowedUDPPorts = forwardPorts;
};
# services.traefik = {
# enable = true;
# dataDir = "${configDir}/traefik";
# group = "jallen-nas"; # group;
# environmentFiles = [ config.sops.templates."traefik.env".path ];
# static = {
# # dir = "${configDir}/traefik";
# settings = {
# entryPoints = {
# web = {
# address = ":${toString httpPort}";
# asDefault = true;
# http.redirections.entrypoint = {
# to = "websecure";
# scheme = "https";
# };
# };
# websecure = {
# address = ":${toString httpsPort}";
# asDefault = true;
# http.tls.certResolver = "letsencrypt";
# };
# metrics = {
# address = ":${toString metricsPort}"; # Port for metrics
# };
# };
# log = {
# level = "INFO";
# };
# metrics = {
# prometheus = {
# entryPoint = "metrics";
# addEntryPointsLabels = true;
# addServicesLabels = true;
# buckets = [
# 0.1
# 0.3
# 1.2
# 5.0
# ]; # Response time buckets
# };
# };
# certificatesResolvers.letsencrypt.acme = {
# email = letsEncryptEmail;
# storage = "${config.services.traefik.dataDir}/acme.json";
# dnsChallenge = {
# provider = "cloudflare";
# resolvers = [
# "1.1.1.1:53"
# "8.8.8.8:53"
# ];
# };
# };
# # Access the Traefik dashboard on <Traefik IP>:8080
# api = {
# dashboard = true;
# insecure = true;
# };
# experimental = {
# plugins = traefikPlugins;
# };
# };
# };
# dynamic = {
# dir = "/run/traefik";
# files = {
# "serversTransports".settings.http = {
# serversTransports = {
# internal-https = {
# insecureSkipVerify = true;
# };
# http1 = {
# serverName = "localhost";
# disableHTTP2 = true;
# };
# };
# };
# "middlewares-authentik".settings.http = {
# middlewares = {
# authentik = {
# forwardAuth = {
# tls.insecureSkipVerify = true;
# address = "${authUrl}/auth/traefik";
# trustForwardHeader = true;
# authResponseHeaders = [
# "X-authentik-username"
# "X-authentik-groups"
# "X-authentik-email"
# "X-authentik-name"
# "X-authentik-uid"
# "X-authentik-jwt"
# "X-authentik-meta-jwks"
# "X-authentik-meta-outpost"
# "X-authentik-meta-provider"
# "X-authentik-meta-app"
# "X-authentik-meta-version"
# ];
# };
# };
# };
# };
# "middlewares-crowdsec".settings.http = {
# middlewares = {
# crowdsec = {
# plugin = {
# bouncer = {
# enabled = true;
# crowdsecLapiKeyFile = config.sops.secrets."jallen-nas/traefik/crowdsec/lapi-key".path;
# crowdsecLapiScheme = "http";
# crowdsecLapiHost = "localhost:8181";
# crowdsecLapiPath = "/";
# crowdsecLapiTLSInsecureVerify = false;
# crowdsecCapiMachineIdFile = config.sops.secrets."jallen-nas/traefik/crowdsec/capi-machine-id".path;
# crowdsecCapiPasswordFile = config.sops.secrets."jallen-nas/traefik/crowdsec/capi-password".path;
# crowdsecCapiScenarios = [ ];
# };
# };
# };
# };
# };
# "middlewares-geoblock".settings.http = {
# middlewares = {
# whitelist-geoblock = {
# plugin = {
# geoblock = {
# silentStartUp = false;
# allowLocalRequests = true;
# logLocalRequests = false;
# logAllowedRequests = false;
# logApiRequests = false;
# api = "https://get.geojs.io/v1/ip/country/{ip}";
# apiTimeoutMs = 500;
# cacheSize = 25;
# forceMonthlyUpdate = true;
# allowUnknownCountries = false;
# unknownCountryApiResponse = "nil";
# blackListMode = false;
# countries = [
# "CA"
# "US"
# ];
# };
# };
# };
# };
# };
# "middlewares-ipallowlist".settings.http = {
# middlewares = {
# internal-ipallowlist = {
# ipAllowList = {
# sourceRange = [
# "127.0.0.1/32"
# "10.0.1.0/24"
# ];
# };
# };
# };
# };
# "services-auth".settings.http = {
# services = {
# auth.loadBalancer.servers = [
# {
# url = authUrl;
# }
# ];
# };
# };
# "services-cache".settings.http = {
# services = {
# cache.loadBalancer = {
# servers = [
# {
# url = cacheUrl;
# }
# ];
# serversTransport = "http1";
# };
# };
# };
# "services-nginx".settings.http = {
# services = {
# nginx.loadBalancer.servers = [
# {
# url = "http://localhost:8188";
# }
# ];
# };
# };
# "services-generated".settings.http = reverseProxyServiceConfigs;
# "routers-auth".settings.http = {
# routers = {
# auth = {
# entryPoints = [ "websecure" ];
# rule = "HostRegexp(`{subdomain:[a-z]+}.mjallen.dev`) && PathPrefix(`/outpost.goauthentik.io/`)";
# service = "auth";
# middlewares = [
# "crowdsec"
# "whitelist-geoblock"
# ];
# priority = 15;
# tls.certResolver = "letsencrypt";
# };
# };
# };
# "routers-matrix2".settings.http = {
# routers = {
# matrix2 = {
# entryPoints = [ "websecure" ];
# rule = "Host(`matrix.mjallen.dev`) && PathPrefix(`/.well-known/matrix/`)";
# service = "nginx";
# middlewares = [
# "crowdsec"
# "whitelist-geoblock"
# ];
# priority = 1;
# tls.certResolver = "letsencrypt";
# };
# };
# };
# "routers-matrix3".settings.http = {
# routers = {
# matrix3 = {
# entryPoints = [ "websecure" ];
# rule = "Host(`mjallen.dev`) && PathPrefix(`/.well-known/matrix/`)";
# service = "nginx";
# middlewares = [
# "crowdsec"
# "whitelist-geoblock"
# ];
# priority = 1;
# tls.certResolver = "letsencrypt";
# };
# };
# };
# "routers-cache".settings.http = {
# routers = {
# cache = {
# entryPoints = [ "websecure" ];
# rule = "Host(`cache.${domain}`)";
# service = "cache";
# middlewares = [ ];
# priority = 10;
# tls.certResolver = "letsencrypt";
# };
# };
# };
# "home-assistant".settings.http = {
# services = {
# hass.loadBalancer.servers = [
# {
# url = hassUrl;
# }
# ];
# };
# routers = {
# hass = {
# entryPoints = [ "websecure" ];
# rule = "Host(`hass.${domain}`)";
# service = "hass";
# middlewares = [
# "crowdsec"
# "whitelist-geoblock"
# # "authentik"
# ];
# priority = 10;
# tls.certResolver = "letsencrypt";
# };
# };
# };
# "routers-generated".settings.http = reverseProxyRouterConfigs;
# };
# };
# };
};
}

View File

@@ -1,42 +0,0 @@
{ lib, namespace, ... }:
with lib;
let
inherit (lib.${namespace}) mkOpt;
in
{
options.${namespace}.services.traefik = {
enable = mkEnableOption "enable traefik";
extraServices = mkOpt (types.listOf (
types.submodule {
options = {
name = mkOpt types.str "" "Name of the service";
url = mkOpt types.str "http://localhost:8080" "Url of the service";
};
}
)) [ ] "List of extra services to forward";
extraRouters = mkOpt (types.listOf (
types.submodule {
options = {
entryPoints = mkOpt (types.listOf types.str) [ "websecure" ] "Entrypoint";
subdomain = mkOpt types.str "" "subdomain of the service";
service = mkOpt types.str "" "name of the service";
middlewares = mkOpt (types.listOf (
types.enum [
"authentik"
"onlyoffice-websocket"
"crowdsec"
"whitelist-geoblock"
"internal-ipallowlist"
]
)) [ ] "List of middlewares to enable";
};
}
)) [ ] "List of extra services to forward";
reverseProxies =
mkOpt (types.listOf types.attrs) [ ]
"List of reverse proxy configurations from mkReverseProxy";
};
}

View File

@@ -1,76 +0,0 @@
{
config,
lib,
namespace,
...
}:
with lib;
let
cfg = config.${namespace}.services.traefik;
in
{
config = mkIf cfg.enable {
sops = {
secrets = {
"jallen-nas/traefik/crowdsec/lapi-key" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/crowdsec/capi-machine-id" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/crowdsec/capi-password" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/cloudflare-dns-api-token" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/cloudflare-zone-api-token" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/cloudflare-api-key" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
"jallen-nas/traefik/cloudflare-email" = {
sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
};
templates = {
"traefik.env" = {
content = ''
CLOUDFLARE_DNS_API_TOKEN=${config.sops.placeholder."jallen-nas/traefik/cloudflare-dns-api-token"}
CLOUDFLARE_ZONE_API_TOKEN=${config.sops.placeholder."jallen-nas/traefik/cloudflare-zone-api-token"}
CLOUDFLARE_API_KEY=${config.sops.placeholder."jallen-nas/traefik/cloudflare-api-key"}
CLOUDFLARE_EMAIL=${config.sops.placeholder."jallen-nas/traefik/cloudflare-email"}
'';
owner = config.users.users.traefik.name;
group = config.users.users.traefik.group;
restartUnits = [ "traefik.service" ];
};
};
};
};
}

View File

@@ -1,122 +0,0 @@
{ ... }:
_final: _super: {
# ${namespace} = super.${namespace} // {
# linuxPackages_rpi5 = super.linuxPackagesFor (
# super.${namespace}.linux-rpi.override { stdenv = super.ccacheStdenv; }
# );
# linuxPackages_rpi4 = super.linuxPackagesFor (
# super.${namespace}.linux-rpi.override {
# stdenv = super.ccacheStdenv;
# rpiVersion = 4;
# }
# );
# libraspberrypi = super.${namespace}.libraspberrypi.override { stdenv = super.ccacheStdenv; };
# raspberrypi-utils = super.${namespace}.raspberrypi-utils.override { stdenv = super.ccacheStdenv; };
# linuxPackages_cachyos = super.${namespace}.linuxPackages_cachyos.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-lto = super.${namespace}.linuxPackages_cachyos-lto.override {
# # stdenv = clangCcacheStdenv;
# # };
# # linuxPackages_cachyos-lto-full = super.${namespace}.linuxPackages_cachyos-lto-full.override {
# # stdenv = clangCcacheStdenv;
# # };
# linuxPackages_cachyos-lts = super.${namespace}.linuxPackages_cachyos-lts.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-lts-lto = super.${namespace}.linuxPackages_cachyos-lts-lto.override {
# # stdenv = clangCcacheStdenv;
# # };
# # linuxPackages_cachyos-lto-znver4 = super.${namespace}.linuxPackages_cachyos-lto-znver4.override {
# # stdenv = clangCcacheStdenv;
# # };
# linuxPackages_cachyos-server = super.${namespace}.linuxPackages_cachyos-server.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-server-lto = super.${namespace}.linuxPackages_cachyos-server-lto.override {
# # stdenv = clangCcacheStdenv;
# # };
# # linuxPackages_cachyos-server-lto-znver4 =
# # super.${namespace}.linuxPackages_cachyos-server-lto-znver4.override
# # { stdenv = clangCcacheStdenv; };
# linuxPackages_cachyos-rc = super.${namespace}.linuxPackages_cachyos-rc.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-rc-lto = super.${namespace}.linuxPackages_cachyos-rc-lto.override {
# # stdenv = clangCcacheStdenv;
# # };
# # linuxPackages_cachyos-rc-lto-znver4 =
# # super.${namespace}.linuxPackages_cachyos-rc-lto-znver4.override
# # { stdenv = clangCcacheStdenv; };
# linuxPackages_cachyos-hardened = super.${namespace}.linuxPackages_cachyos-hardened.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-hardened-lto =
# # super.${namespace}.linuxPackages_cachyos-hardened-lto.override
# # { stdenv = clangCcacheStdenv; };
# # linuxPackages_cachyos-hardened-lto-znver4 =
# # super.${namespace}.linuxPackages_cachyos-hardened-lto-znver4.override
# # { stdenv = clangCcacheStdenv; };
# linuxPackages_cachyos-deckify = super.${namespace}.linuxPackages_cachyos-deckify.override {
# stdenv = super.ccacheStdenv;
# };
# # linuxPackages_cachyos-deckify-lto = super.${namespace}.linuxPackages_cachyos-deckify-lto.override {
# # stdenv = clangCcacheStdenv;
# # };
# };
# raspberrypi-utils = super.${namespace}.raspberrypi-utils;
# raspberrypi-udev-rules = super.${namespace}.udev-rules;
# mesa = super.mesa.override { buildPackages.stdenv = super.ccacheStdenv; };
# # "webkitgtk_4_1" = super.stable."webkitgtk_4_1".override { clangStdenv = super.ccacheStdenv; };
# # "webkitgtk_6_0" = super."webkitgtk_6_0".override { clangStdenv = super.ccacheStdenv; };
# "jellyfin-ffmpeg" = super."jellyfin-ffmpeg".override {
# ffmpeg_7-full = super.ffmpeg_7-full.override { stdenv = super.ccacheStdenv; };
# };
# # "ffmpeg-headless-rpi" = super."ffmpeg-headless-rpi".override { ffmpeg = super.ffmpeg_7.override { stdenv = super.ccacheStdenv; }; };
# # rocmPackages = super.rocmPackages // {
# # hipblaslt = super.rocmPackages.hipblaslt.override {
# # stdenv = super.ccacheStdenv;
# # inherit gpuTargets;
# # };
# # rocblas = super.rocmPackages.rocblas.override {
# # # stdenv = super.ccacheStdenv;
# # inherit gpuTargets;
# # };
# # rocsolver = super.rocmPackages.rocsolver.override {
# # # stdenv = super.ccacheStdenv;
# # inherit gpuTargets;
# # };
# # };
# pcsx2 = super.pcsx2.override {
# llvmPackages = super.llvmPackages // {
# stdenv = super.ccacheStdenv;
# };
# };
# driversi686Linux = super.driversi686Linux // {
# mesa = super.driversi686Linux.mesa.override {
# stdenv = super.ccacheStdenv;
# buildPackages = super.driversi686Linux.mesa.buildPackages // {
# stdenv = super.ccacheStdenv;
# };
# };
# };
# kdePackages = super.kdePackages // {
# qt3d = super.kdePackages.qt3d.override {
# qtbase = super.kdePackages.qtbase.override { stdenv = super.ccacheStdenv; };
# };
# qtwebengine = super.stable.kdePackages.qtwebengine; # .override { stdenv = super.ccacheStdenv; };
# };
# # piper-tts = super.piper-tts.overridePythonAttrs (oldAttrs: {
# # pythonCatchConflictsPhase = null;
# # });
}

View File

@@ -1,5 +0,0 @@
{ ... }:
_final: _prev: {
# home-assistant = final.unstable.home-assistant;
# home-assistant-custom-components = final.unstable.home-assistant-custom-components;
}

View File

@@ -0,0 +1,4 @@
{ inputs, ... }:
_final: _prev: {
mjallen-lib = (import ../../lib { inherit inputs; }).mjallen-lib;
}

View File

@@ -0,0 +1,33 @@
{
lib,
python3Packages,
}:
python3Packages.buildPythonPackage rec {
pname = "littlefs-python";
version = "0.17.1";
pyproject = true;
src = python3Packages.fetchPypi {
pname = "littlefs_python";
inherit version;
hash = "sha256-O8D9Tnf5T6ZVlRdRfPqj38dCUkcayW4a5fWQaJ4ErtA=";
};
build-system = with python3Packages; [
setuptools
setuptools-scm
cython
];
doCheck = false;
pythonImportsCheck = [ "littlefs" ];
meta = with lib; {
description = "Python bindings for littlefs, the filesystem designed for small embedded targets";
homepage = "https://github.com/jrast/littlefs-python";
license = licenses.mit;
maintainers = [ ];
};
}

View File

@@ -3,6 +3,8 @@ jallen-nas:
nas_pool: ENC[AES256_GCM,data:LBiUC/5qMFUnWUWYZgRPrGopdPd6oWB0+xe1S+GiOMtSIsBH34ZoE8U/v1HmxR17mt0x169xq7iXAQZTCZ/Vd8KGmecTK7hC+H6kmSUcwsuoPiVyoSPdet3Zb716eXGWmnSD6QlReUpq6xiCqOwKUkgNgRtkdc92PAEcmbrw1tfooxTesxB3n9pSCXAkwsPxJWl7nLrCZIf6wOZci/TiwFJf534/YPKIz8q5JxX+E+VeQ4NNRfZxn4EqlMDgmNcEcuHdflqTNAlDmREqhN0XNREUaFveQ01T5sFb6XHorEHpUlKIzDpMV4LKjZQMZax4T+6nbGpUa5kf/Gr3xeOpMpTGNir1bM8oPQGP/Iz9u4AjGP56+JYcqUBcxG1wwNFIqBrrC+Bf7vdjGxgMClwW5AbMtGXwE9y+dSM9MMkj8kiaK1zWZfyIqRBheXtXUhPIjJSR8fmnVtKW358E7ynC9R14AsA3qxpxEc4+VmF7cJEzjStP//FRSuUFRlvgIcGBfncvt0b+ecEk8WostYAMHhqpyHtW2hG5orv6qFupLz0VCBbFLqlIEMG1d/EfjulGqWN4fGIhlAGpssvuo8r/9bOz4efTwODnKJqX5YfOPhFDAJZzj7pgFgAjf8/xAgelAU1yR3nlj2PR9itEAApY0L0FvnC4fEMBqlpINM8gGeNcfTraIYo7bqVhOT5sVOXmru+nRoyG1I01rJ1lQpis5Kqt+HWGa43fi81dtTm7kj/4bOPSPrJimIOD37O3GRlbiiGIhy/Ta/iVqzRsYeUZOyIQT+IjZ4pX5tgJ/AxASVzdRd9GluexPdUGVDb9Kjf7mo7aYsXyWDBP7ZoXDQGHndrlTlrQreDLgcwCXo1hHEn9YkIUfYpBd5Th7LJrsaNWXH838S+9sDqSCGdVPVcH0HC8x5T5Uo3Jb833uaQjtaXsSaAgaRkcEtAHz4LO5kKii3AgP0vA,iv:ny8qQhSrfokW3iS0KXtCVYgtvj07c25jfEUCIExD7eI=,tag:QD8C37p3gUJr42NHiL7PHw==,type:str] nas_pool: ENC[AES256_GCM,data:LBiUC/5qMFUnWUWYZgRPrGopdPd6oWB0+xe1S+GiOMtSIsBH34ZoE8U/v1HmxR17mt0x169xq7iXAQZTCZ/Vd8KGmecTK7hC+H6kmSUcwsuoPiVyoSPdet3Zb716eXGWmnSD6QlReUpq6xiCqOwKUkgNgRtkdc92PAEcmbrw1tfooxTesxB3n9pSCXAkwsPxJWl7nLrCZIf6wOZci/TiwFJf534/YPKIz8q5JxX+E+VeQ4NNRfZxn4EqlMDgmNcEcuHdflqTNAlDmREqhN0XNREUaFveQ01T5sFb6XHorEHpUlKIzDpMV4LKjZQMZax4T+6nbGpUa5kf/Gr3xeOpMpTGNir1bM8oPQGP/Iz9u4AjGP56+JYcqUBcxG1wwNFIqBrrC+Bf7vdjGxgMClwW5AbMtGXwE9y+dSM9MMkj8kiaK1zWZfyIqRBheXtXUhPIjJSR8fmnVtKW358E7ynC9R14AsA3qxpxEc4+VmF7cJEzjStP//FRSuUFRlvgIcGBfncvt0b+ecEk8WostYAMHhqpyHtW2hG5orv6qFupLz0VCBbFLqlIEMG1d/EfjulGqWN4fGIhlAGpssvuo8r/9bOz4efTwODnKJqX5YfOPhFDAJZzj7pgFgAjf8/xAgelAU1yR3nlj2PR9itEAApY0L0FvnC4fEMBqlpINM8gGeNcfTraIYo7bqVhOT5sVOXmru+nRoyG1I01rJ1lQpis5Kqt+HWGa43fi81dtTm7kj/4bOPSPrJimIOD37O3GRlbiiGIhy/Ta/iVqzRsYeUZOyIQT+IjZ4pX5tgJ/AxASVzdRd9GluexPdUGVDb9Kjf7mo7aYsXyWDBP7ZoXDQGHndrlTlrQreDLgcwCXo1hHEn9YkIUfYpBd5Th7LJrsaNWXH838S+9sDqSCGdVPVcH0HC8x5T5Uo3Jb833uaQjtaXsSaAgaRkcEtAHz4LO5kKii3AgP0vA,iv:ny8qQhSrfokW3iS0KXtCVYgtvj07c25jfEUCIExD7eI=,tag:QD8C37p3gUJr42NHiL7PHw==,type:str]
ups_password: ENC[AES256_GCM,data:tYuJ9nU3E2/Ko6Y=,iv:lQq+g68lKCp1rmPvS/84xGIXHxD9zY5zZrrjEJlY8Hs=,tag:p6McEr+sXGAQyMAz1Kaxfw==,type:str] ups_password: ENC[AES256_GCM,data:tYuJ9nU3E2/Ko6Y=,iv:lQq+g68lKCp1rmPvS/84xGIXHxD9zY5zZrrjEJlY8Hs=,tag:p6McEr+sXGAQyMAz1Kaxfw==,type:str]
authentik-env: ENC[AES256_GCM,data:PhHiiDJuKx/LKbJR6wx0HknqAs+fnAilA2HsMHwl0N3CMQ0pa+qKEB9x0a16Jr0yC9F4OKD7k98Q4wHbQWuE8IORB9CaiWVQzwJEaFvQ1wdv0wtHC23Aq5ppUPG941xArpF40/64vLYYa8w5Q1wxQr6xeg4VZwpSahIRAa6tB4eMAgopl4QeXGMskaPrL7A9Eu6lXt5LQJkCEFRuyL1XX5W33/l0HYeovgevhqTcbRmOLiG8r4XOihQDUtVWIhW8X3iDlCsgNEgxJE2s+7UuqwetvHpLCQMEyPfITx6FMI6vw8+raLTwQC7fDWXyqjWIJ3/xds7DTcBjJZMj72S6tggX0QLDfnrtjIG0iVNmbRDE2Cv96VJVdV6B381B2XKYx1EThjgucxbmp2Gz4+dpGu3O+rNxlfd9VR7KDA1FH2ddPr8JMhRpeBYbYpxCfuKqgKgfBqvxdI7lV2/alsqLZ3RdzRxi3mCilrldnKEw9YzEJEh0UU2L9J2bP8GJWpyfQsSGnNjpGL3k877e7R0NrKle7ertp2NZKccrKCXyYDGbfERrfmtN2ebaWZXmtbj9Hf/PZBQyXa8onf85QeuY5574pvm8+TZRGorhuMyKi/19lOuEgrAayDM8lQZUDW/QWmU3qf8dO4LAbE7HpzJfv0nEgnKbqVUrV4wcgHYPWNSCFLfdW8eVISgIgZBNA/FD836fwBTCwB91jfWI8g9yrK0l+fvk7RL7Spz7XoK/YIELhojoS6LLr/1wgP2atekDaUBMKw==,iv:w6M8cm+5eCkGPJiD0NkBgZuIVjYPUd9d1yp95y/BwyQ=,tag:SgOpa23x395CefA9zvI5GA==,type:str] authentik-env: ENC[AES256_GCM,data:PhHiiDJuKx/LKbJR6wx0HknqAs+fnAilA2HsMHwl0N3CMQ0pa+qKEB9x0a16Jr0yC9F4OKD7k98Q4wHbQWuE8IORB9CaiWVQzwJEaFvQ1wdv0wtHC23Aq5ppUPG941xArpF40/64vLYYa8w5Q1wxQr6xeg4VZwpSahIRAa6tB4eMAgopl4QeXGMskaPrL7A9Eu6lXt5LQJkCEFRuyL1XX5W33/l0HYeovgevhqTcbRmOLiG8r4XOihQDUtVWIhW8X3iDlCsgNEgxJE2s+7UuqwetvHpLCQMEyPfITx6FMI6vw8+raLTwQC7fDWXyqjWIJ3/xds7DTcBjJZMj72S6tggX0QLDfnrtjIG0iVNmbRDE2Cv96VJVdV6B381B2XKYx1EThjgucxbmp2Gz4+dpGu3O+rNxlfd9VR7KDA1FH2ddPr8JMhRpeBYbYpxCfuKqgKgfBqvxdI7lV2/alsqLZ3RdzRxi3mCilrldnKEw9YzEJEh0UU2L9J2bP8GJWpyfQsSGnNjpGL3k877e7R0NrKle7ertp2NZKccrKCXyYDGbfERrfmtN2ebaWZXmtbj9Hf/PZBQyXa8onf85QeuY5574pvm8+TZRGorhuMyKi/19lOuEgrAayDM8lQZUDW/QWmU3qf8dO4LAbE7HpzJfv0nEgnKbqVUrV4wcgHYPWNSCFLfdW8eVISgIgZBNA/FD836fwBTCwB91jfWI8g9yrK0l+fvk7RL7Spz7XoK/YIELhojoS6LLr/1wgP2atekDaUBMKw==,iv:w6M8cm+5eCkGPJiD0NkBgZuIVjYPUd9d1yp95y/BwyQ=,tag:SgOpa23x395CefA9zvI5GA==,type:str]
authentik-rac:
token: ENC[AES256_GCM,data:+vI8x8AM9eT35YPQGKmvHH0iZ4IvNUWnSO+05GT57+rC/uRXTaP+PSM+6r6RbUClkd6Pms4HiEEtNxjL,iv:RwNCgBEYLgr/ZgXUbazNJHjCMDXXHIpJQSqSMkFR/Uw=,tag:tqTxdVYOSgxI/IsuypSYdg==,type:str]
traefik: traefik:
crowdsec: crowdsec:
lapi-key: ENC[AES256_GCM,data:tEEr+KtGPseweqWn7eyrZwZBl+pPqzQqr5cmlYZF2ugm9pF4sUwBdEy21A==,iv:x1h0Op29Ta15dPe1Tfm4c1Mlo85aqvyOgZ5bELRNTGE=,tag:y0R8DHc0ya96n6hLLhteYA==,type:str] lapi-key: ENC[AES256_GCM,data:tEEr+KtGPseweqWn7eyrZwZBl+pPqzQqr5cmlYZF2ugm9pF4sUwBdEy21A==,iv:x1h0Op29Ta15dPe1Tfm4c1Mlo85aqvyOgZ5bELRNTGE=,tag:y0R8DHc0ya96n6hLLhteYA==,type:str]
@@ -83,6 +85,8 @@ jallen-nas:
nas-pub: ENC[AES256_GCM,data:lZF4LJPDb2EmtDrKsOIrNENBCoEDAYzL8tF5mORGxCKEJXhXB5tnsn0DpzNSaxo+aTlW4AhrH6DdgdlhgAyMqlZRnTLcqc7yUT1zFWEerWvpm0IJJRvyjL4LK6HFuSczQNSwbCylPByvmLm1Tw++wp9RUmZpCxesSH1lgKA=,iv:CAVBEC/byHTpdkgoHzHMFgzCZLoBog2H826/L3Vq4Y0=,tag:s9wp5CjlyYHEKzy3m8+FJA==,type:str] nas-pub: ENC[AES256_GCM,data:lZF4LJPDb2EmtDrKsOIrNENBCoEDAYzL8tF5mORGxCKEJXhXB5tnsn0DpzNSaxo+aTlW4AhrH6DdgdlhgAyMqlZRnTLcqc7yUT1zFWEerWvpm0IJJRvyjL4LK6HFuSczQNSwbCylPByvmLm1Tw++wp9RUmZpCxesSH1lgKA=,iv:CAVBEC/byHTpdkgoHzHMFgzCZLoBog2H826/L3Vq4Y0=,tag:s9wp5CjlyYHEKzy3m8+FJA==,type:str]
nas-key: ENC[AES256_GCM,data:QGW6jaXZKwFByIoWa0lJXUkIlHZaZEr58hkd+QpUkUUr8g2TEJkb0bAaNNEhhDS8YmQ7HejtgG+YFneji9C9BDPhIFIlM/GPiGzHggHMx3UfJU3ai78UL6sFlito21MhLKox758FIUNnVIa/8zGfLCymy0/eoe+rodX9J/h6cQ==,iv:HBXKoWLTo4usF6L4B1yA9EzM+qZTYfsHOus8nXwQO6w=,tag:BLfLrZKgD/gADwVngMZoqw==,type:str] nas-key: ENC[AES256_GCM,data:QGW6jaXZKwFByIoWa0lJXUkIlHZaZEr58hkd+QpUkUUr8g2TEJkb0bAaNNEhhDS8YmQ7HejtgG+YFneji9C9BDPhIFIlM/GPiGzHggHMx3UfJU3ai78UL6sFlito21MhLKox758FIUNnVIa/8zGfLCymy0/eoe+rodX9J/h6cQ==,iv:HBXKoWLTo4usF6L4B1yA9EzM+qZTYfsHOus8nXwQO6w=,tag:BLfLrZKgD/gADwVngMZoqw==,type:str]
nas-cert: ENC[AES256_GCM,data:m/eLQPEGWfc8ajF6rHJyyZzuj0UqfnkD/+quDVsY9h55nTFVlky7GbQ2raohs31D8mH7O6AMFsgmkg1vnow7TAuCj06OGhnFHo+oqeqUFIYImfr8cGA+geJJ3dgthSStEzi+gxIKralmWGPVAzcW9DhJm4Y1Ot4mCJ3DRdAALXKjQkO8W7wVfDDSHKKFwwn/Sq4/fdoCanJlxFpLDTuKS4E/CrXC0ojYZJ7ePdx0B/idR4Xm5qxyaE1rysQ45zd9N1HVJlgXi2hHXUCzCxJ5jjx2dht52tkBa+OGWQTQiyXh1gXDhwW2xUkadaKYZ+vPo/VMgZxu44F95/AmuiLGmDumW9hhqlQ7teK897n+R/1HasrUA8Sjshs9Ok9JN/XiZvvO/TJVnEsxdnm5d6xTJ1XI8tHu1A==,iv:dWJIdRj1zWT4Xx0LIZfRENDZWVvDf2XrEizr9+sUr4Q=,tag:uIoLAcpZg1rVP7NYgEgi2A==,type:str] nas-cert: ENC[AES256_GCM,data:m/eLQPEGWfc8ajF6rHJyyZzuj0UqfnkD/+quDVsY9h55nTFVlky7GbQ2raohs31D8mH7O6AMFsgmkg1vnow7TAuCj06OGhnFHo+oqeqUFIYImfr8cGA+geJJ3dgthSStEzi+gxIKralmWGPVAzcW9DhJm4Y1Ot4mCJ3DRdAALXKjQkO8W7wVfDDSHKKFwwn/Sq4/fdoCanJlxFpLDTuKS4E/CrXC0ojYZJ7ePdx0B/idR4Xm5qxyaE1rysQ45zd9N1HVJlgXi2hHXUCzCxJ5jjx2dht52tkBa+OGWQTQiyXh1gXDhwW2xUkadaKYZ+vPo/VMgZxu44F95/AmuiLGmDumW9hhqlQ7teK897n+R/1HasrUA8Sjshs9Ok9JN/XiZvvO/TJVnEsxdnm5d6xTJ1XI8tHu1A==,iv:dWJIdRj1zWT4Xx0LIZfRENDZWVvDf2XrEizr9+sUr4Q=,tag:uIoLAcpZg1rVP7NYgEgi2A==,type:str]
hass-mcp:
token: ENC[AES256_GCM,data:tt25g4KU8EzaWKBXV4olVp80IlnQYLz8IqJ3ktGorEidmtv+8LZDQu8DG+0hmdh7gT2svyzfSxD/8maWPYsW2GMovDsuR/4qpQ9Lxe06n0mDdeFEBEW38Rz6AFUmNCIxUbNkNoDc7grEIi4kZbTTyNEmxwvzF+VkpddT3VBsm8wXH9F5JW8k4imFzxatCAHCw8R64IzgZe7KL6vEIC0vsHfM8vtZMD85eCZEcV9gIPvQEi/8dApd,iv:8V9VaXvGvZ1dlnLKUTsz3yYjmT9lTxpURdygqVJsteM=,tag:ttfUb7Jd0rtkLCotGgRKVA==,type:str]
termix: termix:
client-id: ENC[AES256_GCM,data:BKIni/vc+MhzotU28V75kul9+CxSbmO0a1Pw/ySihejXE87hoYW3bQ==,iv:6GObrAqxxOs/Nz58scc/Mt2kIPte55RUK7EYsJ9zbOY=,tag:J5mg17NRm1KD5DrSSV9OOw==,type:str] client-id: ENC[AES256_GCM,data:BKIni/vc+MhzotU28V75kul9+CxSbmO0a1Pw/ySihejXE87hoYW3bQ==,iv:6GObrAqxxOs/Nz58scc/Mt2kIPte55RUK7EYsJ9zbOY=,tag:J5mg17NRm1KD5DrSSV9OOw==,type:str]
client-secret: ENC[AES256_GCM,data:mkM+2Ou3kbCiPrw4EN9O5rr6+VkZ0qw3HsY5as2YjlyNnH+7K6WEqVIc2BjahaYMf3Uddj0ObRpqK+eFlO4vKLhx3Oe7cyIfOqLDETSPXoNvT4vCasSnboRLNGOYvHorAKum6BYGD8Kw+LFVkl6YeTmaeA7wvt+5jsOlpu8jajw=,iv:Yq3G+xAP2KjRvQ/grVJRZqfFN/W+tEdEYahhufsczkY=,tag:nSa0cgtu6Mt3IcIzVd3Qkg==,type:str] client-secret: ENC[AES256_GCM,data:mkM+2Ou3kbCiPrw4EN9O5rr6+VkZ0qw3HsY5as2YjlyNnH+7K6WEqVIc2BjahaYMf3Uddj0ObRpqK+eFlO4vKLhx3Oe7cyIfOqLDETSPXoNvT4vCasSnboRLNGOYvHorAKum6BYGD8Kw+LFVkl6YeTmaeA7wvt+5jsOlpu8jajw=,iv:Yq3G+xAP2KjRvQ/grVJRZqfFN/W+tEdEYahhufsczkY=,tag:nSa0cgtu6Mt3IcIzVd3Qkg==,type:str]
@@ -233,8 +237,8 @@ sops:
L0gwQm5takNjMkVGNzVlSStJYlUwWDAKP8QA3rRUHYbyyhPC/k0Eq2EIKfjyc7Co L0gwQm5takNjMkVGNzVlSStJYlUwWDAKP8QA3rRUHYbyyhPC/k0Eq2EIKfjyc7Co
7BkHH3msC6h9g42BB5iIYe6KQ+UGxMQBFvp+qSB27jaIfajN5MP0BA== 7BkHH3msC6h9g42BB5iIYe6KQ+UGxMQBFvp+qSB27jaIfajN5MP0BA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-16T16:01:51Z" lastmodified: "2026-03-16T20:25:44Z"
mac: ENC[AES256_GCM,data:m1Fb2vGqgpA20v0SsoqfEDmWxF7TLYcv2KROD1E1LZ+Oewx4UN71pj78rbId25vqedx4qL8fpS4FiwK0KrLfruHxSAnR21+PIdgCVxw5mVqvyDxJTZ7GCli8cGHDs4bL0ZlkY1mGZNPF5QWkzUef98XLX4jEkIozJttnNDL/HzM=,iv:E1zPp/rP+wc01Al8sHpzk5iA7POw1Tf9wiZEmVWpNI0=,tag:JYRMKmPWh+ZxQ26qFZmCoA==,type:str] mac: ENC[AES256_GCM,data:BFsr1muH8kY6EehvD1TCfzkn2F8OStso72FuNCkPZBLKxww5895qm+d+pp+STZD2PlUkBLMqEunLNHSNN49Z50OPaGDJTynoes72A5c0beWd/GV/5NM+2vnJ8S3GjquVhlIp2Lfxa4pjMkGdpcZknKoXIQBHwsMkw/ZhJtE1ceQ=,iv:U5YMcKLQG2vXog7XyohLO//0MAfZaFFH4ucPB2RC8iU=,tag:bQY66SUhzhGf2hgO0zT9Hw==,type:str]
pgp: pgp:
- created_at: "2026-02-06T15:34:30Z" - created_at: "2026-02-06T15:34:30Z"
enc: |- enc: |-

View File

@@ -28,6 +28,10 @@ in
port = 9012; port = 9012;
listenAddress = "[::]"; listenAddress = "[::]";
environmentFile = "/run/secrets/jallen-nas/attic-key"; environmentFile = "/run/secrets/jallen-nas/attic-key";
reverseProxy = {
enable = true;
subdomain = "cache";
};
}; };
authentik = { authentik = {
enable = true; enable = true;
@@ -73,6 +77,10 @@ in
collabora = { collabora = {
enable = true; enable = true;
port = 9980; port = 9980;
reverseProxy = {
enable = true;
subdomain = "office";
};
}; };
crowdsec = { crowdsec = {
enable = true; enable = true;
@@ -220,8 +228,8 @@ in
termix = { termix = {
enable = true; enable = true;
port = 7777; port = 7777;
reverseProxy = enabled;
}; };
traefik = disabled;
unmanic = { unmanic = {
enable = true; enable = true;
port = 8265; port = 8265;

View File

@@ -36,6 +36,8 @@ in
# # Desktop # # # # Desktop # #
# ################################################### # ###################################################
# COSMIC is enabled for occasional local display access.
# headless.enable only disables watchdog/emergency mode, not the display server.
desktop.cosmic = enabled; desktop.cosmic = enabled;
# ################################################### # ###################################################
@@ -69,7 +71,7 @@ in
}; };
}; };
headless.enable = true; headless.enable = false;
# ################################################### # ###################################################
# # Impermanence # # # # Impermanence # #
@@ -96,12 +98,7 @@ in
group = "nextcloud"; group = "nextcloud";
mode = "u=rwx,g=rwx,o=rx"; mode = "u=rwx,g=rwx,o=rx";
} }
{
directory = "/plugins-storage";
user = "traefik";
group = "traefik";
mode = "u=rwx,g=rwx,o=rx";
}
]; ];
}; };
@@ -135,22 +132,22 @@ in
allowPing = true; allowPing = true;
trustedInterfaces = [ "tailscale0" ]; trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = [ allowedTCPPorts = [
80 80 # http
443 443 # https
8080 8080 # traefik dashboard
8008 # restic 8008 # restic
9000 # authentik 9000 # authentik
2342 # grafana 2342 # grafana
51820 # wireguard 51820 # wireguard
1025 1025 # smtp (protonmail bridge)
1143 1143 # imap (protonmail bridge)
10200 10200 # nebula
10300 10300
8127 8127 # llama.cpp server
8280 8280
9943 # onlyoffice 9943 # onlyoffice
4000 # netbootxyz 4000 # netbootxyz tftp/http
4080 # netbootxyz 4080 # netbootxyz web
3000 # gitea 3000 # gitea
2222 # gitea ssh 2222 # gitea ssh
3300 3300
@@ -161,27 +158,31 @@ in
9012 9012
9988 9988
8192 8192
3000 8181 # crowdsec
2222
8181
5432
3001 3001
3333 3333
5201 # iperf 5201 # iperf
8400 8400
9200 9200 # elasticsearch / attic
9233 9233
9980 9980
47984 47984 # sunshine (tcp: control)
47989 47989 # sunshine (tcp: https)
47990 47990 # sunshine (tcp: web)
47998 47998 # sunshine (tcp: video)
47999 47999 # sunshine (tcp: control)
48000 48000 # sunshine (tcp: video)
48010 48010 # sunshine (tcp: rtsp)
3493 # nut 3493 # nut upsd
# removed: 5432 (postgres — internal only, not for external UDP/TCP)
];
allowedUDPPorts = [
51820 # wireguard
5201 # iperf
47998 # sunshine (udp: video)
47999 # sunshine (udp: control)
48000 # sunshine (udp: video)
]; ];
allowedUDPPorts = config.${namespace}.network.firewall.allowedTCPPorts;
}; };
}; };
@@ -264,7 +265,6 @@ in
"nix-apps" "nix-apps"
"jallen-nas" "jallen-nas"
"grafana" "grafana"
"traefik"
"62900" "62900"
"1001" "1001"
]; ];

View File

@@ -57,7 +57,6 @@ in
restic = mkForce disabled; restic = mkForce disabled;
sunshine = mkForce disabled; sunshine = mkForce disabled;
tdarr = mkForce disabled; tdarr = mkForce disabled;
traefik = mkForce disabled;
unmanic = mkForce disabled; unmanic = mkForce disabled;
uptime-kuma = mkForce disabled; uptime-kuma = mkForce disabled;
wyoming = mkForce disabled; wyoming = mkForce disabled;

View File

@@ -256,6 +256,16 @@ in
"jallen-nas/ntfy/auth-users" = { "jallen-nas/ntfy/auth-users" = {
sopsFile = defaultSops; sopsFile = defaultSops;
}; };
# ------------------------------
# authentik-rac
# NOTE: add to nas-secrets.yaml via `sops secrets/nas-secrets.yaml`:
# jallen-nas/authentik-rac/token: <authentik RAC outpost token>
# ------------------------------
"jallen-nas/authentik-rac/token" = {
sopsFile = defaultSops;
restartUnits = [ "podman-authenticRac.service" ];
};
}; };
# ------------------------------ # ------------------------------
@@ -278,6 +288,14 @@ in
restartUnits = [ "podman-free-games-claimer.service" ]; restartUnits = [ "podman-free-games-claimer.service" ];
}; };
"authentik-rac.env" = {
content = ''
AUTHENTIK_TOKEN=${config.sops.placeholder."jallen-nas/authentik-rac/token"}
'';
mode = "0600";
restartUnits = [ "podman-authenticRac.service" ];
};
"paperless.env" = { "paperless.env" = {
content = '' content = ''
PAPERLESS_ADMIN_USER = "mjallen" PAPERLESS_ADMIN_USER = "mjallen"