cleanup
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
concatLists
|
|
||||||
concatMapStrings
|
|
||||||
foldl'
|
|
||||||
genList
|
|
||||||
hasSuffix
|
|
||||||
imap0
|
|
||||||
length
|
|
||||||
mod
|
|
||||||
nameValuePair
|
|
||||||
stringToCharacters
|
|
||||||
sublist
|
|
||||||
substring
|
|
||||||
take
|
|
||||||
;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
base64Table = builtins.listToAttrs (
|
|
||||||
imap0 (i: c: nameValuePair c i) (
|
|
||||||
# The '=' is included so the main algorithm doesn't fail before we can trim the result
|
|
||||||
stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
# Generated using python3:
|
|
||||||
# print(''.join([ chr(n) for n in range(1, 256) ]), file=open('ascii', 'w'))
|
|
||||||
ascii = builtins.readFile ./ascii;
|
|
||||||
|
|
||||||
decode =
|
|
||||||
str:
|
|
||||||
let
|
|
||||||
paddingCount =
|
|
||||||
if hasSuffix "==" str then
|
|
||||||
2
|
|
||||||
else if hasSuffix "=" str then
|
|
||||||
1
|
|
||||||
else
|
|
||||||
0;
|
|
||||||
|
|
||||||
numbers64 = map (c: base64Table.${c}) (stringToCharacters str);
|
|
||||||
|
|
||||||
allBytes = concatLists (
|
|
||||||
genList (
|
|
||||||
i:
|
|
||||||
let
|
|
||||||
v = foldl' (acc: el: acc * 64 + el) 0 (sublist (i * 4) 4 numbers64);
|
|
||||||
in
|
|
||||||
[
|
|
||||||
(mod (v / 256 / 256) 256)
|
|
||||||
(mod (v / 256) 256)
|
|
||||||
(mod v 256)
|
|
||||||
]
|
|
||||||
) (length numbers64 / 4)
|
|
||||||
);
|
|
||||||
|
|
||||||
finalBytes = take (length allBytes - paddingCount) allBytes;
|
|
||||||
|
|
||||||
in
|
|
||||||
concatMapStrings (n: substring (n - 1) 1 ascii) finalBytes;
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,8 @@
|
|||||||
{ inputs, ... }:
|
{ inputs, ... }:
|
||||||
{
|
{
|
||||||
mjallen-lib = {
|
mjallen-lib = {
|
||||||
# Import module utilities
|
|
||||||
module = import ./module { inherit inputs; };
|
module = import ./module { inherit inputs; };
|
||||||
|
|
||||||
# Import file utilities
|
|
||||||
file = import ./file { inherit inputs; };
|
file = import ./file { inherit inputs; };
|
||||||
|
|
||||||
# Import system utilities
|
|
||||||
system = import ./system { inherit inputs; };
|
|
||||||
|
|
||||||
# Import reverse proxy utilities
|
|
||||||
reverseproxy = import ./reverseproxy { inherit inputs; };
|
|
||||||
|
|
||||||
# Import examples
|
|
||||||
examples = import ./examples { inherit inputs; };
|
|
||||||
|
|
||||||
# Import versioning utilities
|
|
||||||
versioning = import ./versioning {
|
versioning = import ./versioning {
|
||||||
lib = inputs.nixpkgs.lib;
|
lib = inputs.nixpkgs.lib;
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Import all examples
|
|
||||||
sops = import ./sops.nix;
|
|
||||||
homeSops = import ./home-sops.nix;
|
|
||||||
fileUtils = import ./file-utils.nix;
|
|
||||||
systemUtils = import ./system-utils.nix;
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
{ lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}.file)
|
|
||||||
readFile
|
|
||||||
pathExists
|
|
||||||
safeImport
|
|
||||||
scanDir
|
|
||||||
getFile
|
|
||||||
importModulesRecursive
|
|
||||||
scanSystems
|
|
||||||
filterNixOSSystems
|
|
||||||
filterDarwinSystems
|
|
||||||
scanHomes
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example of reading a file
|
|
||||||
myFileContent = readFile ./example.txt;
|
|
||||||
|
|
||||||
# Example of checking if a file exists
|
|
||||||
fileExists = pathExists ./example.txt;
|
|
||||||
|
|
||||||
# Example of safely importing a file
|
|
||||||
myConfig = safeImport ./my-config.nix { };
|
|
||||||
|
|
||||||
# Example of scanning a directory
|
|
||||||
directoryContents = scanDir ./modules;
|
|
||||||
|
|
||||||
# Example of getting a file path relative to the flake root
|
|
||||||
flakeFile = getFile "flake.nix";
|
|
||||||
|
|
||||||
# Example of importing modules recursively
|
|
||||||
modules = importModulesRecursive ./modules;
|
|
||||||
|
|
||||||
# Example of scanning systems
|
|
||||||
allSystems = scanSystems ./systems;
|
|
||||||
|
|
||||||
# Example of filtering systems
|
|
||||||
nixosSystems = filterNixOSSystems allSystems;
|
|
||||||
darwinSystems = filterDarwinSystems allSystems;
|
|
||||||
|
|
||||||
# Example of scanning homes
|
|
||||||
allHomes = scanHomes ./homes;
|
|
||||||
|
|
||||||
# Example of using these functions together
|
|
||||||
nixosConfigurations = lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{ system, hostname, ... }:
|
|
||||||
{
|
|
||||||
name = hostname;
|
|
||||||
value = lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules = [
|
|
||||||
{ networking.hostName = hostname; }
|
|
||||||
]
|
|
||||||
++ importModulesRecursive ./modules/nixos;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) nixosSystems;
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}.module) mkModule mkOpt;
|
|
||||||
in
|
|
||||||
mkModule {
|
|
||||||
name = "sops";
|
|
||||||
description = "SOPS secret management for home-manager";
|
|
||||||
options = {
|
|
||||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
|
||||||
|
|
||||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [ ] "SSH Key paths to use.";
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
age
|
|
||||||
sops
|
|
||||||
ssh-to-age
|
|
||||||
];
|
|
||||||
|
|
||||||
sops = {
|
|
||||||
inherit (config.${namespace}.sops) defaultSopsFile;
|
|
||||||
defaultSopsFormat = "yaml";
|
|
||||||
|
|
||||||
age = {
|
|
||||||
generateKey = true;
|
|
||||||
keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
|
|
||||||
sshKeyPaths = [
|
|
||||||
"${config.home.homeDirectory}/.ssh/id_ed25519"
|
|
||||||
]
|
|
||||||
++ config.${namespace}.sops.sshKeyPaths;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# Example usage of the reverse proxy utilities
|
|
||||||
{ lib, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace} - lib.reverseproxy)
|
|
||||||
mkReverseProxy
|
|
||||||
mkReverseProxies
|
|
||||||
templates
|
|
||||||
middlewares
|
|
||||||
urls
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example 1: Simple reverse proxy for a local service
|
|
||||||
simpleProxy = mkReverseProxy {
|
|
||||||
name = "myapp";
|
|
||||||
subdomain = "myapp";
|
|
||||||
url = "http://127.0.0.1:3000";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 2: Authenticated service with custom middlewares
|
|
||||||
authProxy = mkReverseProxy {
|
|
||||||
name = "admin-panel";
|
|
||||||
subdomain = "admin";
|
|
||||||
url = "http://127.0.0.1:8080";
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 3: Container-based service
|
|
||||||
containerProxy = mkReverseProxy {
|
|
||||||
name = "nextcloud";
|
|
||||||
subdomain = "cloud";
|
|
||||||
url = urls.container "nextcloud" 80;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 4: Multiple proxies at once
|
|
||||||
multipleProxies = mkReverseProxies [
|
|
||||||
{
|
|
||||||
name = "grafana";
|
|
||||||
subdomain = "grafana";
|
|
||||||
url = urls.localhost 3000;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "prometheus";
|
|
||||||
subdomain = "prometheus";
|
|
||||||
url = urls.localhost 9090;
|
|
||||||
middlewares = middlewares.internal;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "alertmanager";
|
|
||||||
subdomain = "alerts";
|
|
||||||
url = urls.localhost 9093;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Example 5: Using templates for common patterns
|
|
||||||
webappExample = templates.webapp {
|
|
||||||
name = "webapp";
|
|
||||||
subdomain = "app";
|
|
||||||
port = 8080;
|
|
||||||
};
|
|
||||||
|
|
||||||
authWebappExample = templates.authWebapp {
|
|
||||||
name = "secure-app";
|
|
||||||
subdomain = "secure";
|
|
||||||
port = 9000;
|
|
||||||
};
|
|
||||||
|
|
||||||
containerExample = templates.containerService {
|
|
||||||
name = "gitea";
|
|
||||||
subdomain = "git";
|
|
||||||
containerName = "gitea";
|
|
||||||
port = 3000;
|
|
||||||
};
|
|
||||||
|
|
||||||
internalExample = templates.internalService {
|
|
||||||
name = "internal-api";
|
|
||||||
subdomain = "api-internal";
|
|
||||||
port = 8000;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example 6: Custom domain and advanced configuration
|
|
||||||
customProxy = mkReverseProxy {
|
|
||||||
name = "custom-service";
|
|
||||||
subdomain = "custom";
|
|
||||||
url = "http://10.0.1.100:8080";
|
|
||||||
domain = "example.com";
|
|
||||||
priority = 20;
|
|
||||||
rule = "Host(`custom.example.com`) && PathPrefix(`/api`)";
|
|
||||||
middlewares = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"rate-limit"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example usage in a Traefik configuration:
|
|
||||||
#
|
|
||||||
# mjallen.services.traefik = {
|
|
||||||
# enable = true;
|
|
||||||
# extraServices = multipleProxies.extraServices;
|
|
||||||
# extraRouters = multipleProxies.extraRouters;
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# Or for individual proxies:
|
|
||||||
#
|
|
||||||
# mjallen.services.traefik = {
|
|
||||||
# enable = true;
|
|
||||||
# extraServices = [ simpleProxy.service ];
|
|
||||||
# extraRouters = [{
|
|
||||||
# inherit (simpleProxy.router) subdomain entryPoints middlewares;
|
|
||||||
# service = simpleProxy.router.service;
|
|
||||||
# }];
|
|
||||||
# };
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
namespace,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib.${namespace}.module) mkModule mkOpt mkBoolOpt;
|
|
||||||
in
|
|
||||||
mkModule {
|
|
||||||
name = "sops";
|
|
||||||
description = "SOPS secret management";
|
|
||||||
options = {
|
|
||||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
|
||||||
|
|
||||||
generateAgeKey = mkBoolOpt true "Whether to automatically generate an age key if one doesn't exist.";
|
|
||||||
|
|
||||||
ageKeyPath =
|
|
||||||
mkOpt (lib.types.nullOr lib.types.str) null
|
|
||||||
"Custom path to the age key file. If null, will use the default path.";
|
|
||||||
|
|
||||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
|
||||||
] "SSH Key paths to use.";
|
|
||||||
|
|
||||||
validateSopsFiles = mkBoolOpt false "Whether to validate that sops files exist.";
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
sops = {
|
|
||||||
inherit (config.${namespace}.sops) defaultSopsFile validateSopsFiles;
|
|
||||||
|
|
||||||
age = {
|
|
||||||
inherit (config.${namespace}.sops) generateAgeKey;
|
|
||||||
|
|
||||||
keyFile =
|
|
||||||
if config.${namespace}.sops.ageKeyPath != null then
|
|
||||||
config.${namespace}.sops.ageKeyPath
|
|
||||||
else
|
|
||||||
"${config.users.users.${config.${namespace}.user.name}.home}/.config/sops/age/keys.txt";
|
|
||||||
|
|
||||||
sshKeyPaths = config.${namespace}.sops.sshKeyPaths;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
{ inputs, namespace, ... }:
|
|
||||||
let
|
|
||||||
inherit (inputs.self.${namespace} - lib.system.common)
|
|
||||||
mkExtendedLib
|
|
||||||
mkNixpkgsConfig
|
|
||||||
mkHomeConfigs
|
|
||||||
mkHomeManagerConfig
|
|
||||||
mkSpecialArgs
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Example of creating NixOS configurations
|
|
||||||
nixosConfigurations =
|
|
||||||
let
|
|
||||||
# Get all systems
|
|
||||||
allSystems = inputs.self.${namespace} - lib.file.scanSystems ../systems;
|
|
||||||
|
|
||||||
# Filter for NixOS systems
|
|
||||||
nixosSystems = inputs.self.${namespace} - lib.file.filterNixOSSystems allSystems;
|
|
||||||
in
|
|
||||||
inputs.nixpkgs.lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{ system, hostname, ... }:
|
|
||||||
let
|
|
||||||
# Create extended lib with mjallen-lib
|
|
||||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
|
||||||
|
|
||||||
# Find matching home configurations for this system
|
|
||||||
matchingHomes = mkHomeConfigs {
|
|
||||||
flake = inputs.self;
|
|
||||||
inherit system hostname;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create home-manager configuration
|
|
||||||
homeManagerConfig = mkHomeManagerConfig {
|
|
||||||
inherit
|
|
||||||
extendedLib
|
|
||||||
inputs
|
|
||||||
system
|
|
||||||
matchingHomes
|
|
||||||
;
|
|
||||||
isNixOS = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = hostname;
|
|
||||||
value = inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
|
|
||||||
# Pass special arguments to modules
|
|
||||||
specialArgs = mkSpecialArgs {
|
|
||||||
inherit inputs hostname extendedLib;
|
|
||||||
username = "mjallen";
|
|
||||||
};
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
# Set lib to extended lib
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
|
|
||||||
# Configure nixpkgs
|
|
||||||
{
|
|
||||||
nixpkgs = {
|
|
||||||
inherit system;
|
|
||||||
}
|
|
||||||
// mkNixpkgsConfig inputs.self;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Import home-manager module
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
|
|
||||||
# Auto-inject home configurations
|
|
||||||
homeManagerConfig
|
|
||||||
|
|
||||||
# Import all nixos modules recursively
|
|
||||||
../${system}/${hostname}
|
|
||||||
]
|
|
||||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/nixos);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) nixosSystems;
|
|
||||||
|
|
||||||
# Example of creating home-manager configurations
|
|
||||||
homeConfigurations =
|
|
||||||
let
|
|
||||||
# Get all homes
|
|
||||||
allHomes = inputs.self.${namespace} - lib.file.scanHomes ../homes;
|
|
||||||
in
|
|
||||||
inputs.nixpkgs.lib.mapAttrs' (
|
|
||||||
_name:
|
|
||||||
{
|
|
||||||
system,
|
|
||||||
username,
|
|
||||||
hostname,
|
|
||||||
userAtHost,
|
|
||||||
path,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
# Create extended lib with mjallen-lib
|
|
||||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = userAtHost;
|
|
||||||
value = inputs.home-manager.lib.homeManagerConfiguration {
|
|
||||||
pkgs = import inputs.nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
inherit ((mkNixpkgsConfig inputs.self)) config overlays;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraSpecialArgs = {
|
|
||||||
inherit
|
|
||||||
inputs
|
|
||||||
hostname
|
|
||||||
username
|
|
||||||
system
|
|
||||||
;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
};
|
|
||||||
|
|
||||||
modules = [
|
|
||||||
# Set lib to extended lib
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
|
|
||||||
# Import the home configuration
|
|
||||||
path
|
|
||||||
]
|
|
||||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/home);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) allHomes;
|
|
||||||
}
|
|
||||||
@@ -14,8 +14,6 @@ let
|
|||||||
mkDefault
|
mkDefault
|
||||||
mkForce
|
mkForce
|
||||||
;
|
;
|
||||||
|
|
||||||
base64Lib = import ../base64 { inherit inputs; };
|
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -26,7 +24,9 @@ rec {
|
|||||||
mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
|
mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
|
||||||
) modules;
|
) modules;
|
||||||
|
|
||||||
# Create a module with common options
|
# Create a NixOS module with standard options (enable, port, reverseProxy,
|
||||||
|
# firewall, user, postgresql, redis) and optional caller-supplied options and
|
||||||
|
# config. All config is gated behind `cfg.enable`.
|
||||||
mkModule =
|
mkModule =
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
@@ -51,9 +51,6 @@ rec {
|
|||||||
defaultConfig = {
|
defaultConfig = {
|
||||||
# Caddy reverse proxy: when reverseProxy.enable = true, contribute this
|
# Caddy reverse proxy: when reverseProxy.enable = true, contribute this
|
||||||
# service's named-matcher block into the shared wildcard virtual host.
|
# service's named-matcher block into the shared wildcard virtual host.
|
||||||
# The TLS block stays in the caddy module itself; all services merge
|
|
||||||
# their handle blocks into the same "*.${domain}" extraConfig via the
|
|
||||||
# lines type (which concatenates automatically).
|
|
||||||
services.caddy.virtualHosts."*.${cfg.reverseProxy.domain}" = lib.mkIf cfg.reverseProxy.enable {
|
services.caddy.virtualHosts."*.${cfg.reverseProxy.domain}" = lib.mkIf cfg.reverseProxy.enable {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
@${name} host ${fqdn}
|
@${name} host ${fqdn}
|
||||||
@@ -79,20 +76,15 @@ rec {
|
|||||||
groups.${name} = { };
|
groups.${name} = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.${serviceName} = {
|
# Ensure the service waits for the filesystem that hosts configDir and
|
||||||
requires = [
|
# dataDir to be mounted before starting. RequiresMountsFor is the
|
||||||
"media-nas-main.mount"
|
# idiomatic systemd way to express this: if the paths live on the root
|
||||||
# "openvpn-us.protonvpn.udp.service"
|
# filesystem the directive is silently ignored, so it is safe on every
|
||||||
];
|
# host — not just the NAS.
|
||||||
after = lib.mkForce [
|
systemd.services.${serviceName}.unitConfig.RequiresMountsFor = [
|
||||||
"media-nas-main.mount"
|
cfg.configDir
|
||||||
# "openvpn-us.protonvpn.udp.service"
|
cfg.dataDir
|
||||||
];
|
];
|
||||||
# serviceConfig = {
|
|
||||||
# NetworkNamespacePath = lib.mkIf cfg.enableVpn "/run/netns/vpn";
|
|
||||||
# # Consider also setting DNS *inside* the netns (see note below).
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
postgresql = lib.mkIf cfg.configureDb {
|
postgresql = lib.mkIf cfg.configureDb {
|
||||||
@@ -110,12 +102,6 @@ rec {
|
|||||||
port = cfg.redis.port;
|
port = cfg.redis.port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# systemd.tmpfiles.rules = [
|
|
||||||
# "d ${cfg.configDir} 0700 ${name} ${name} - -"
|
|
||||||
# # "d ${cfg.configDir}/server-files 0775 ${name} ${name} - -"
|
|
||||||
# # "d ${cfg.configDir}/user-files 0775 ${name} ${name} - -"
|
|
||||||
# ];
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
@@ -134,44 +120,42 @@ rec {
|
|||||||
options = {
|
options = {
|
||||||
enable = lib.mkEnableOption description;
|
enable = lib.mkEnableOption description;
|
||||||
|
|
||||||
port = mkOpt types.int 80 "Port for ${name} to be hosted on";
|
port = mkOpt types.int 80 "Port for ${name} to listen on";
|
||||||
|
|
||||||
configDir = mkOpt types.str "/media/nas/main/appdata" "Path to the config dir";
|
configDir = mkOpt types.str "/var/lib/${name}" "Path to the config directory";
|
||||||
|
|
||||||
dataDir = mkOpt types.str "/media/nas/main" "Path to the data dir";
|
dataDir = mkOpt types.str "/var/lib/${name}/data" "Path to the data directory";
|
||||||
|
|
||||||
createUser = mkBoolOpt false "create a user for this module/service";
|
createUser = mkBoolOpt false "Create a dedicated system user for this service";
|
||||||
|
|
||||||
configureDb = mkBoolOpt false "Manage db for this service";
|
configureDb = mkBoolOpt false "Manage a PostgreSQL database for this service";
|
||||||
|
|
||||||
environmentFile = mkOpt types.str "" "Environment File";
|
environmentFile =
|
||||||
|
mkOpt (types.nullOr types.str) null
|
||||||
|
"Path to an environment file (EnvironmentFile=)";
|
||||||
|
|
||||||
puid = mkOpt types.str "911" "default user id";
|
puid = mkOpt types.str "911" "User ID for container-based services";
|
||||||
|
|
||||||
pgid = mkOpt types.str "1000" "default group id";
|
pgid = mkOpt types.str "100" "Group ID for container-based services";
|
||||||
|
|
||||||
timeZone = mkOpt types.str "America/Chicago" "default timezone";
|
timeZone = mkOpt types.str "UTC" "Timezone for container-based services";
|
||||||
|
|
||||||
listenAddress = mkOpt types.str "0.0.0.0" "Environment File";
|
listenAddress = mkOpt types.str "0.0.0.0" "Listen address";
|
||||||
|
|
||||||
openFirewall = mkBoolOpt true "Open the firewall";
|
openFirewall = mkBoolOpt true "Open firewall ports for this service";
|
||||||
|
|
||||||
enableVpn = mkBoolOpt true "Enable routing through VPN";
|
|
||||||
|
|
||||||
redis = {
|
redis = {
|
||||||
enable = lib.mkEnableOption "enable redis";
|
enable = lib.mkEnableOption "a dedicated Redis server for this service";
|
||||||
|
port = mkOpt types.int 6379 "Redis port for ${name}";
|
||||||
port = mkOpt types.int 80 "Port for ${name} redis to be hosted on";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hashedPassword =
|
hashedPassword =
|
||||||
mkOpt (types.nullOr types.str)
|
mkOpt (types.nullOr types.str) null
|
||||||
"$y$j9T$EkPXmsmIMFFZ.WRrBYCxS1$P0kwo6e4.WM5DsqUcEqWC3MrZp5KfCjxffraMFZWu06"
|
"Hashed password (e.g. for web-based authentication)";
|
||||||
"Hashed password for code-server authentication";
|
|
||||||
|
|
||||||
extraEnvironment =
|
extraEnvironment =
|
||||||
mkOpt (types.attrsOf types.str) { }
|
mkOpt (types.attrsOf types.str) { }
|
||||||
"Extra environment variables for code-server";
|
"Extra environment variables passed to the service";
|
||||||
|
|
||||||
reverseProxy = mkReverseProxyOpt name;
|
reverseProxy = mkReverseProxyOpt name;
|
||||||
}
|
}
|
||||||
@@ -181,58 +165,15 @@ rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# container
|
# ---------------------------------------------------------------------------
|
||||||
mkContainer =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
localAddress ? "127.0.0.1",
|
|
||||||
ports ? [ 80 ],
|
|
||||||
bindMounts ? { },
|
|
||||||
config ? { },
|
|
||||||
}:
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
containers.${name} = {
|
|
||||||
inherit localAddress bindMounts;
|
|
||||||
|
|
||||||
config = config // {
|
|
||||||
networking = {
|
|
||||||
firewall = {
|
|
||||||
enable = true;
|
|
||||||
allowedTCPPorts = ports;
|
|
||||||
};
|
|
||||||
# Use systemd-resolved inside the container
|
|
||||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
|
||||||
useHostResolvConf = lib.mkForce false;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.resolved.enable = true;
|
|
||||||
system.stateVersion = "23.11";
|
|
||||||
};
|
|
||||||
autoStart = lib.mkDefault true;
|
|
||||||
privateNetwork = lib.mkDefault true;
|
|
||||||
hostAddress = lib.mkDefault "10.0.1.3";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
nat.forwardPorts = map (port: {
|
|
||||||
destination = lib.mkDefault "${localAddress}:${toString port}";
|
|
||||||
sourcePort = lib.mkDefault port;
|
|
||||||
}) ports;
|
|
||||||
firewall = {
|
|
||||||
allowedTCPPorts = ports;
|
|
||||||
allowedUDPPorts = ports;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Migrated mjallen utilities
|
|
||||||
# Option creation helpers
|
# Option creation helpers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
mkOpt =
|
mkOpt =
|
||||||
type: default: description:
|
type: default: description:
|
||||||
mkOption { inherit type default description; };
|
mkOption { inherit type default description; };
|
||||||
|
|
||||||
mkOpt' = type: default: mkOpt type default null;
|
mkOpt' = type: default: mkOpt type default "";
|
||||||
|
|
||||||
mkBoolOpt = mkOpt types.bool;
|
mkBoolOpt = mkOpt types.bool;
|
||||||
|
|
||||||
@@ -245,26 +186,28 @@ rec {
|
|||||||
|
|
||||||
domain = mkOpt types.str "mjallen.dev" "Base domain for the reverse proxy";
|
domain = mkOpt types.str "mjallen.dev" "Base domain for the reverse proxy";
|
||||||
|
|
||||||
# Override the upstream URL if the backend is not on localhost at cfg.port.
|
|
||||||
# Leave empty to use http://127.0.0.1:<port> automatically.
|
|
||||||
upstreamUrl =
|
upstreamUrl =
|
||||||
mkOpt (types.nullOr types.str) null
|
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>.";
|
"Override upstream URL (e.g. for a service 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 inside this virtual host block";
|
||||||
extraCaddyConfig = mkOpt types.lines "" "Extra Caddyfile directives for this virtual host block";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Standard enable/disable patterns
|
# ---------------------------------------------------------------------------
|
||||||
|
# Convenience shorthands
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
enabled = {
|
enabled = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
disabled = {
|
disabled = {
|
||||||
enable = false;
|
enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# String utilities
|
# String utilities
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
capitalize =
|
capitalize =
|
||||||
s:
|
s:
|
||||||
let
|
let
|
||||||
@@ -272,10 +215,16 @@ rec {
|
|||||||
in
|
in
|
||||||
if len == 0 then "" else (toUpper (substring 0 1 s)) + (substring 1 len s);
|
if len == 0 then "" else (toUpper (substring 0 1 s)) + (substring 1 len s);
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# Boolean utilities
|
# Boolean utilities
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
boolToNum = bool: if bool then 1 else 0;
|
boolToNum = bool: if bool then 1 else 0;
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# Attribute manipulation utilities
|
# Attribute manipulation utilities
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
default-attrs = mapAttrs (_key: mkDefault);
|
default-attrs = mapAttrs (_key: mkDefault);
|
||||||
|
|
||||||
force-attrs = mapAttrs (_key: mkForce);
|
force-attrs = mapAttrs (_key: mkForce);
|
||||||
@@ -284,4 +233,3 @@ rec {
|
|||||||
|
|
||||||
nested-force-attrs = mapAttrs (_key: force-attrs);
|
nested-force-attrs = mapAttrs (_key: force-attrs);
|
||||||
}
|
}
|
||||||
// base64Lib
|
|
||||||
|
|||||||
@@ -1,220 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib)
|
|
||||||
listToAttrs
|
|
||||||
nameValuePair
|
|
||||||
;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
# Create a service configuration for Traefik
|
|
||||||
mkService =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
loadBalancer ? { },
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit name url;
|
|
||||||
config = {
|
|
||||||
loadBalancer = {
|
|
||||||
servers = [ { inherit url; } ];
|
|
||||||
}
|
|
||||||
// loadBalancer;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create a router configuration for Traefik
|
|
||||||
mkRouter =
|
|
||||||
{
|
|
||||||
subdomain,
|
|
||||||
domain ? "mjallen.dev",
|
|
||||||
service,
|
|
||||||
entryPoints ? [ "websecure" ],
|
|
||||||
middlewares ? [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
],
|
|
||||||
priority ? null,
|
|
||||||
rule ? null,
|
|
||||||
tls ? {
|
|
||||||
certResolver = "letsencrypt";
|
|
||||||
},
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit
|
|
||||||
subdomain
|
|
||||||
service
|
|
||||||
entryPoints
|
|
||||||
middlewares
|
|
||||||
;
|
|
||||||
config = {
|
|
||||||
inherit
|
|
||||||
entryPoints
|
|
||||||
service
|
|
||||||
middlewares
|
|
||||||
tls
|
|
||||||
;
|
|
||||||
rule = if rule != null then rule else "Host(`${subdomain}.${domain}`)";
|
|
||||||
}
|
|
||||||
// (if priority != null then { inherit priority; } else { });
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create both service and router for a simple reverse proxy setup
|
|
||||||
mkReverseProxy =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
subdomain,
|
|
||||||
url,
|
|
||||||
domain ? "mjallen.dev",
|
|
||||||
entryPoints ? [ "websecure" ],
|
|
||||||
middlewares ? [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
],
|
|
||||||
priority ? null,
|
|
||||||
rule ? null,
|
|
||||||
tls ? {
|
|
||||||
certResolver = "letsencrypt";
|
|
||||||
},
|
|
||||||
loadBalancer ? { },
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
service = mkService {
|
|
||||||
inherit name url loadBalancer;
|
|
||||||
};
|
|
||||||
router = mkRouter {
|
|
||||||
inherit
|
|
||||||
subdomain
|
|
||||||
domain
|
|
||||||
entryPoints
|
|
||||||
middlewares
|
|
||||||
priority
|
|
||||||
rule
|
|
||||||
tls
|
|
||||||
;
|
|
||||||
service = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Convert a list of services to the format expected by Traefik module
|
|
||||||
servicesToConfig =
|
|
||||||
services: listToAttrs (map (service: nameValuePair service.name service.config) services);
|
|
||||||
|
|
||||||
# Convert a list of routers to the format expected by Traefik module
|
|
||||||
routersToConfig =
|
|
||||||
routers: listToAttrs (map (router: nameValuePair router.subdomain router.config) routers);
|
|
||||||
|
|
||||||
# Helper to create multiple reverse proxies at once
|
|
||||||
mkReverseProxies =
|
|
||||||
proxies:
|
|
||||||
let
|
|
||||||
results = map mkReverseProxy proxies;
|
|
||||||
services = map (result: result.service) results;
|
|
||||||
routers = map (result: result.router) results;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services = servicesToConfig services;
|
|
||||||
routers = routersToConfig routers;
|
|
||||||
extraServices = services;
|
|
||||||
extraRouters = map (router: {
|
|
||||||
inherit (router) subdomain entryPoints middlewares;
|
|
||||||
service = router.service;
|
|
||||||
}) routers;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Common middleware configurations
|
|
||||||
middlewares = {
|
|
||||||
# Authentication middleware
|
|
||||||
auth = [ "authentik" ];
|
|
||||||
|
|
||||||
# Basic security (default)
|
|
||||||
basic = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Internal only access
|
|
||||||
internal = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"internal-ipallowlist"
|
|
||||||
];
|
|
||||||
|
|
||||||
# WebSocket support
|
|
||||||
websocket = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"onlyoffice-websocket"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Authenticated with basic security
|
|
||||||
authBasic = [
|
|
||||||
"crowdsec"
|
|
||||||
"whitelist-geoblock"
|
|
||||||
"authentik"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Common service URL builders
|
|
||||||
urls = {
|
|
||||||
# Local container service
|
|
||||||
container =
|
|
||||||
containerName: port: "http://\${config.containers.${containerName}.localAddress}:${toString port}";
|
|
||||||
|
|
||||||
# Local host service
|
|
||||||
localhost = port: "http://127.0.0.1:${toString port}";
|
|
||||||
|
|
||||||
# Network service
|
|
||||||
network = ip: port: "http://${ip}:${toString port}";
|
|
||||||
|
|
||||||
# Server IP service (using your server IP pattern)
|
|
||||||
server = port: "http://\${serverIp}:${toString port}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Pre-configured reverse proxy templates
|
|
||||||
templates = {
|
|
||||||
# Standard web application
|
|
||||||
webapp =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Authenticated web application
|
|
||||||
authWebapp =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.authBasic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Container-based service
|
|
||||||
containerService =
|
|
||||||
{ containerName, port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.container containerName port;
|
|
||||||
middlewares = middlewares.basic;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
|
|
||||||
# Internal-only service
|
|
||||||
internalService =
|
|
||||||
{ port, ... }@args:
|
|
||||||
mkReverseProxy (
|
|
||||||
{
|
|
||||||
url = urls.localhost port;
|
|
||||||
middlewares = middlewares.internal;
|
|
||||||
}
|
|
||||||
// args
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
{ inputs, namespace }:
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs.lib) filterAttrs mapAttrs';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
mkExtendedLib =
|
|
||||||
flake: nixpkgs:
|
|
||||||
nixpkgs.lib.extend (
|
|
||||||
_final: _prev: {
|
|
||||||
mjallen = flake.${namespace} - lib;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
mkNixpkgsConfig = flake: {
|
|
||||||
overlays = builtins.attrValues flake.overlays;
|
|
||||||
config = {
|
|
||||||
allowAliases = false;
|
|
||||||
allowUnfree = true;
|
|
||||||
permittedInsecurePackages = [
|
|
||||||
# Add any permitted insecure packages here
|
|
||||||
"mbedtls-2.28.10"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mkHomeConfigs =
|
|
||||||
{
|
|
||||||
flake,
|
|
||||||
system,
|
|
||||||
hostname,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (flake.${namespace} - lib.file) scanHomes;
|
|
||||||
homesPath = ../../homes;
|
|
||||||
allHomes = scanHomes homesPath;
|
|
||||||
in
|
|
||||||
filterAttrs (
|
|
||||||
_name: homeConfig: homeConfig.system == system && homeConfig.hostname == hostname
|
|
||||||
) allHomes;
|
|
||||||
|
|
||||||
mkHomeManagerConfig =
|
|
||||||
{
|
|
||||||
extendedLib,
|
|
||||||
inputs,
|
|
||||||
system,
|
|
||||||
matchingHomes,
|
|
||||||
isNixOS ? true,
|
|
||||||
}:
|
|
||||||
if matchingHomes != { } then
|
|
||||||
{
|
|
||||||
home-manager = {
|
|
||||||
useGlobalPkgs = true;
|
|
||||||
useUserPackages = true;
|
|
||||||
extraSpecialArgs = {
|
|
||||||
inherit inputs system;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
};
|
|
||||||
sharedModules = [
|
|
||||||
{ _module.args.lib = extendedLib; }
|
|
||||||
]
|
|
||||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../../modules/home);
|
|
||||||
users = mapAttrs' (_name: homeConfig: {
|
|
||||||
name = homeConfig.username;
|
|
||||||
value = {
|
|
||||||
imports = [ homeConfig.path ];
|
|
||||||
home = {
|
|
||||||
inherit (homeConfig) username;
|
|
||||||
homeDirectory = inputs.nixpkgs.lib.mkDefault (
|
|
||||||
if isNixOS then "/home/${homeConfig.username}" else "/Users/${homeConfig.username}"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if isNixOS then
|
|
||||||
{
|
|
||||||
_module.args.username = homeConfig.username;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
}) matchingHomes;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ };
|
|
||||||
|
|
||||||
mkSpecialArgs =
|
|
||||||
{
|
|
||||||
inputs,
|
|
||||||
hostname,
|
|
||||||
username,
|
|
||||||
extendedLib,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit inputs hostname username;
|
|
||||||
inherit (inputs) self;
|
|
||||||
lib = extendedLib;
|
|
||||||
namespace = "mjallen";
|
|
||||||
format = "system";
|
|
||||||
host = hostname;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
# Common utilities used by system builders
|
|
||||||
common = import ./common.nix { inherit inputs; };
|
|
||||||
}
|
|
||||||
@@ -77,7 +77,7 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
dataDir = "/media/nas/main/nix-app-data/grafana";
|
dataDir = "${cfg.configDir}/grafana";
|
||||||
|
|
||||||
provision = {
|
provision = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ in
|
|||||||
|
|
||||||
dataPath = mkOption {
|
dataPath = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/media/nas/main/ocis";
|
default = "/var/lib/ocis";
|
||||||
};
|
};
|
||||||
|
|
||||||
configPath = mkOption {
|
configPath = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/media/nas/main/nix-app-data/ocis";
|
default = "/var/lib/ocis/config";
|
||||||
};
|
};
|
||||||
|
|
||||||
puid = mkOption {
|
puid = mkOption {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ with lib;
|
|||||||
|
|
||||||
configPath = mkOption {
|
configPath = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/media/nas/main/nix-app-data/your_spotify";
|
default = "/var/lib/your-spotify";
|
||||||
};
|
};
|
||||||
|
|
||||||
puid = mkOption {
|
puid = mkOption {
|
||||||
@@ -46,12 +46,12 @@ with lib;
|
|||||||
|
|
||||||
pgid = mkOption {
|
pgid = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "1000";
|
default = "100";
|
||||||
};
|
};
|
||||||
|
|
||||||
timeZone = mkOption {
|
timeZone = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "America/Chicago";
|
default = "UTC";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ in
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./boot.nix
|
./boot.nix
|
||||||
|
./nas-defaults.nix
|
||||||
./apps.nix
|
./apps.nix
|
||||||
./disabled.nix
|
./disabled.nix
|
||||||
# ./nas-pool.nix
|
# ./nas-pool.nix
|
||||||
@@ -18,7 +19,6 @@ in
|
|||||||
./services.nix
|
./services.nix
|
||||||
./sops.nix
|
./sops.nix
|
||||||
./vpn.nix
|
./vpn.nix
|
||||||
# testcontainer
|
|
||||||
];
|
];
|
||||||
|
|
||||||
services.kmscon = disabled;
|
services.kmscon = disabled;
|
||||||
|
|||||||
86
systems/x86_64-linux/jallen-nas/nas-defaults.nix
Normal file
86
systems/x86_64-linux/jallen-nas/nas-defaults.nix
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# NAS-wide defaults for all mkModule services.
|
||||||
|
#
|
||||||
|
# Every service's configDir and dataDir default to paths on the NAS bcachefs
|
||||||
|
# pool. Setting them here via lib.mkDefault means individual service
|
||||||
|
# declarations in apps.nix only need to override when they deviate from the
|
||||||
|
# convention, keeping apps.nix concise.
|
||||||
|
#
|
||||||
|
# The companion RequiresMountsFor in mkModule uses these paths to derive the
|
||||||
|
# correct systemd mount dependency automatically — no service needs to hardcode
|
||||||
|
# "media-nas-main.mount" by name.
|
||||||
|
{ lib, namespace, ... }:
|
||||||
|
let
|
||||||
|
appdata = "/media/nas/main/appdata";
|
||||||
|
data = "/media/nas/main";
|
||||||
|
|
||||||
|
svcDefault = name: {
|
||||||
|
${namespace}.services.${name} = {
|
||||||
|
configDir = lib.mkDefault appdata;
|
||||||
|
dataDir = lib.mkDefault data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Bespoke services that define their own path options (not via mkModule).
|
||||||
|
# Set NAS-specific paths here so the module defaults stay generic.
|
||||||
|
${namespace}.services.your_spotify.configPath = lib.mkDefault "${appdata}/your_spotify";
|
||||||
|
${namespace}.services.ocis = {
|
||||||
|
dataPath = lib.mkDefault "${data}/ocis";
|
||||||
|
configPath = lib.mkDefault "${appdata}/ocis";
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = map svcDefault [
|
||||||
|
"actual"
|
||||||
|
"ai"
|
||||||
|
"arrs"
|
||||||
|
"attic"
|
||||||
|
"authentik"
|
||||||
|
"authentikRac"
|
||||||
|
"booklore"
|
||||||
|
"caddy"
|
||||||
|
"calibre"
|
||||||
|
"calibre-web"
|
||||||
|
"code-server"
|
||||||
|
"collabora"
|
||||||
|
"coturn"
|
||||||
|
"crowdsec"
|
||||||
|
"dispatcharr"
|
||||||
|
"free-games-claimer"
|
||||||
|
"gitea"
|
||||||
|
"glance"
|
||||||
|
"glances"
|
||||||
|
"grafana"
|
||||||
|
"guacd"
|
||||||
|
"headscale"
|
||||||
|
"immich"
|
||||||
|
"jellyfin"
|
||||||
|
"jellyseerr"
|
||||||
|
"lubelogger"
|
||||||
|
"manyfold"
|
||||||
|
"matrix"
|
||||||
|
"minecraft"
|
||||||
|
"mongodb"
|
||||||
|
"nebula"
|
||||||
|
"nebula-lighthouse"
|
||||||
|
"netbootxyz"
|
||||||
|
"nextcloud"
|
||||||
|
"ntfy"
|
||||||
|
"onlyoffice"
|
||||||
|
"opencloud"
|
||||||
|
"orca-slicer"
|
||||||
|
"paperless"
|
||||||
|
"paperless-ai"
|
||||||
|
"protonmail-bridge"
|
||||||
|
"restic"
|
||||||
|
"sparky-fitness"
|
||||||
|
"sparky-fitness-server"
|
||||||
|
"sparky-fitness-db"
|
||||||
|
"sunshine"
|
||||||
|
"tdarr"
|
||||||
|
"termix"
|
||||||
|
"tunarr"
|
||||||
|
"unmanic"
|
||||||
|
"uptime-kuma"
|
||||||
|
"wyoming"
|
||||||
|
];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user