feat(nixos): add pikachu homepage guest
This commit is contained in:
@@ -55,5 +55,7 @@
|
||||
- On Pikachu, `nix copy --to ssh://pikachu` accepted a small `nix store add-file` probe,
|
||||
but rejected locally built system paths that lacked trusted signatures.
|
||||
Use a sudo `nix-store --import` path for unsigned deploy closures.
|
||||
- Public DNS entries are not managed through the NixOS configuration.
|
||||
Do not describe NixOS route choices as public-DNS management.
|
||||
- Do not hand-author `hardware-configuration.nix` for a host that has not been generated on that machine.
|
||||
Generate it on the target system or live ISO, then stage it before evaluating the flake.
|
||||
|
||||
@@ -25,6 +25,14 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
registry.homepage.${config.networking.hostName}.actualbudget = {
|
||||
tab = "Apps";
|
||||
section = "Other";
|
||||
name = "Actual Budget";
|
||||
description = "Finance";
|
||||
icon = "actual-budget.png";
|
||||
};
|
||||
|
||||
guests.actualbudget = {
|
||||
interior = {
|
||||
modules.services.actualbudget = {
|
||||
|
||||
@@ -90,6 +90,15 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
registry.homepage.${config.networking.hostName}.copyparty = {
|
||||
tab = "Apps";
|
||||
section = "Files";
|
||||
name = "Copyparty";
|
||||
description = "Files";
|
||||
icon = "copyparty.svg";
|
||||
href = lib.mkIf cfg.reverseProxy.enable "https://${cfg.reverseProxy.route.domain}/?h";
|
||||
};
|
||||
|
||||
guests.copyparty = {
|
||||
interior.modules.services.copyparty = {
|
||||
enable = true;
|
||||
|
||||
32
configs/nixos/guests/homepage.nix
Normal file
32
configs/nixos/guests/homepage.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.guests.homepage;
|
||||
in
|
||||
{
|
||||
options.guests.homepage = {
|
||||
allowedHosts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "home" ];
|
||||
description = "Host headers accepted by Homepage.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
guests.homepage = {
|
||||
interior.modules.services.homepage = {
|
||||
enable = true;
|
||||
inherit (cfg) allowedHosts;
|
||||
};
|
||||
|
||||
limits = {
|
||||
memory = lib.mkDefault "1G";
|
||||
cpu = lib.mkDefault "100%";
|
||||
tasksMax = lib.mkDefault 256;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -48,6 +48,14 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
registry.homepage.${config.networking.hostName}.navidrome = {
|
||||
tab = "Apps";
|
||||
section = "Media";
|
||||
name = "Navidrome";
|
||||
description = "Music";
|
||||
icon = "navidrome.png";
|
||||
};
|
||||
|
||||
guests.navidrome = {
|
||||
interior.modules.services.navidrome.enable = true;
|
||||
|
||||
|
||||
@@ -144,6 +144,12 @@
|
||||
address = "10.23.20.109";
|
||||
};
|
||||
|
||||
guests.homepage = {
|
||||
enable = true;
|
||||
vlan = 20;
|
||||
address = "10.23.20.46";
|
||||
};
|
||||
|
||||
guests.copyparty = {
|
||||
enable = true;
|
||||
vlan = 20;
|
||||
|
||||
132
configs/nixos/modules/services/homepage.nix
Normal file
132
configs/nixos/modules/services/homepage.nix
Normal file
@@ -0,0 +1,132 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
registry,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.services.homepage;
|
||||
|
||||
mkRegistryPath = registryName: host: entry: "registry.${registryName}.${host}.${entry}";
|
||||
|
||||
homepageEntries = lib.concatLists (
|
||||
lib.mapAttrsToList (
|
||||
host: entries:
|
||||
lib.mapAttrsToList (entry: homepage: {
|
||||
inherit host entry homepage;
|
||||
composite = registry.join host entry;
|
||||
}) entries
|
||||
) registry.homepage
|
||||
);
|
||||
|
||||
mkHref = item:
|
||||
if item.homepage.href != null then
|
||||
item.homepage.href
|
||||
else if (item.composite.route or null) != null && item.composite.route.port != null then
|
||||
"https://${item.composite.route.domain}"
|
||||
else
|
||||
throw "${mkRegistryPath "homepage" item.host item.entry} needs href or a matching TCP route entry";
|
||||
|
||||
mkServiceAttrs = item:
|
||||
lib.filterAttrs (_: value: value != null) {
|
||||
href = mkHref item;
|
||||
inherit (item.homepage) description icon;
|
||||
};
|
||||
|
||||
sortedEntries = lib.sort (left: right: left.homepage.name < right.homepage.name) homepageEntries;
|
||||
|
||||
insertEntry = acc: item:
|
||||
acc
|
||||
// {
|
||||
${item.homepage.tab} = (acc.${item.homepage.tab} or { })
|
||||
// {
|
||||
${item.homepage.section} = (acc.${item.homepage.tab}.${item.homepage.section} or [ ]) ++ [
|
||||
{ ${item.homepage.name} = mkServiceAttrs item; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
entriesByTab = lib.foldl' insertEntry { } sortedEntries;
|
||||
|
||||
tabOrder = [
|
||||
"Apps"
|
||||
"Download"
|
||||
"System"
|
||||
];
|
||||
|
||||
orderedTabs = tabOrder ++ lib.filter (tab: !lib.elem tab tabOrder) (lib.attrNames entriesByTab);
|
||||
|
||||
mkTab = tab:
|
||||
let
|
||||
sections = entriesByTab.${tab};
|
||||
in
|
||||
{
|
||||
${tab} = map (section: { ${section} = sections.${section}; }) (lib.attrNames sections);
|
||||
};
|
||||
|
||||
homepageServices = map mkTab (lib.filter (tab: lib.hasAttr tab entriesByTab) orderedTabs);
|
||||
in
|
||||
{
|
||||
options.modules.services.homepage = {
|
||||
enable = lib.mkEnableOption "Homepage Dashboard";
|
||||
|
||||
listenPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 80;
|
||||
description = "Port for Homepage to bind to.";
|
||||
};
|
||||
|
||||
allowedHosts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "home" ];
|
||||
description = "Host headers accepted by Homepage.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.homepage-dashboard = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
inherit (cfg) listenPort;
|
||||
allowedHosts = lib.concatStringsSep "," cfg.allowedHosts;
|
||||
services = homepageServices;
|
||||
settings = {
|
||||
title = "Tracion";
|
||||
theme = "dark";
|
||||
color = "slate";
|
||||
showStats = false;
|
||||
hideVersion = true;
|
||||
bookmarksStyle = "icons";
|
||||
useEqualHeights = true;
|
||||
layout = {
|
||||
Apps = {
|
||||
style = "row";
|
||||
columns = 1;
|
||||
tab = "Apps";
|
||||
Media = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
Files = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
Other = {
|
||||
style = "row";
|
||||
columns = 3;
|
||||
iconsOnly = true;
|
||||
};
|
||||
};
|
||||
Download = {
|
||||
style = "row";
|
||||
columns = 1;
|
||||
tab = "Download";
|
||||
};
|
||||
System = {
|
||||
tab = "System";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
45
configs/nixos/registry/homepage.nix
Normal file
45
configs/nixos/registry/homepage.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
tab = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "Apps";
|
||||
description = "Homepage tab that contains this entry.";
|
||||
};
|
||||
|
||||
section = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "Media";
|
||||
description = "Homepage section that contains this entry.";
|
||||
};
|
||||
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "Navidrome";
|
||||
description = "Homepage display name for this entry.";
|
||||
};
|
||||
|
||||
description = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "Music";
|
||||
description = "Homepage description for this entry.";
|
||||
};
|
||||
|
||||
icon = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "navidrome.png";
|
||||
description = "Homepage icon for this entry.";
|
||||
};
|
||||
|
||||
href = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "https://music.alexion.dev";
|
||||
description = "Homepage link override for this entry.";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -50,10 +50,9 @@
|
||||
- immich
|
||||
- romm
|
||||
- gitea
|
||||
- vikunja (?)
|
||||
- nginxproxymanager (gradual migration to nginx guest)
|
||||
- adguard
|
||||
- homepage
|
||||
- manage DNS rewrites for local service names such as `home`
|
||||
|
||||
## raichu proxmox -> nixos
|
||||
- dwn torrent (vpn)
|
||||
|
||||
Reference in New Issue
Block a user