feat: Homepage

This commit is contained in:
marthsincemelee
2026-04-20 14:46:44 +02:00
parent e1ea5b03dc
commit 191e860455
14 changed files with 259 additions and 25 deletions
+14 -3
View File
@@ -6,11 +6,13 @@
... ...
}: }:
let let
cfg = config.my.profiles.audiobookshelf; cfg = config.my.profiles.actual;
hostName = config.networking.hostName;
port = 40465;
in in
{ {
options.my.profiles.actual = with lib; { options.my.profiles.actual = with lib; {
enable = mkEnableOption "Audio Book Service"; enable = mkEnableOption "Actual budget service";
}; };
@@ -19,7 +21,7 @@ in
enable = true; enable = true;
openFirewall = true; openFirewall = true;
settings = { settings = {
port = 40465; port = port;
hostname = "0.0.0.0"; hostname = "0.0.0.0";
}; };
}; };
@@ -28,6 +30,15 @@ in
actual-server actual-server
]; ];
my.homepage.services = [
{
group = "Finance";
name = "Actual";
description = "Budgeting";
href = "http://${hostName}:${toString port}";
}
];
systemd.services.actual = { systemd.services.actual = {
after = [ "network-online.target" ]; after = [ "network-online.target" ];
}; };
@@ -7,6 +7,7 @@
}: }:
let let
cfg = config.my.profiles.audiobookshelf; cfg = config.my.profiles.audiobookshelf;
hostName = config.networking.hostName;
in in
{ {
options.my.profiles.audiobookshelf = with lib; { options.my.profiles.audiobookshelf = with lib; {
@@ -26,6 +27,15 @@ in
audiobookshelf audiobookshelf
]; ];
my.homepage.services = [
{
group = "Media";
name = "Audiobookshelf";
description = "Audiobooks and podcasts";
href = "http://${hostName}:63834";
}
];
systemd.services.audiobookshelf = { systemd.services.audiobookshelf = {
after = [ "network-online.target" ]; after = [ "network-online.target" ];
}; };
@@ -0,0 +1,39 @@
[
{
Developer = [
{
Github = [
{
abbr = "GH";
href = "https://github.com/";
}
];
}
];
}
{
Social = [
{
Reddit = [
{
icon = "reddit.png";
href = "https://reddit.com/";
description = "The front page of the internet";
}
];
}
];
}
{
Entertainment = [
{
YouTube = [
{
abbr = "YT";
href = "https://youtube.com/";
}
];
}
];
}
]
@@ -1,16 +0,0 @@
---
- Developer:
- Github:
- abbr: GH
href: https://github.com/
- Social:
- Reddit:
- icon: reddit.png
href: https://reddit.com/
description: The front page of the internet
- Entertainment:
- YouTube:
- abbr: YT
href: https://youtube.com/
+67 -3
View File
@@ -6,9 +6,69 @@
}: }:
let let
cfg = config.my.profiles.homepage; cfg = config.my.profiles.homepage;
dashboardPort = 8082;
dashboardHost = config.networking.hostName;
dashboardUrl = "http://${dashboardHost}:${toString dashboardPort}";
groupedServices =
lib.foldl'
(
acc: entry:
acc
// {
${entry.group} = (acc.${entry.group} or [ ]) ++ [ entry ];
}
)
{ }
config.my.homepage.services;
homepageServices = lib.mapAttrsToList (
group: entries:
{
${group} = map (
entry:
{
${entry.name} = builtins.removeAttrs entry [
"group"
"name"
];
}
) entries;
}
) groupedServices;
in in
{ {
options.my.homepage.services = with lib; mkOption {
type = types.listOf (
types.submodule {
options = {
group = mkOption {
type = types.str;
description = "Homepage service group";
};
name = mkOption {
type = types.str;
description = "Homepage service name";
};
description = mkOption {
type = types.str;
description = "Homepage service description";
};
href = mkOption {
type = types.str;
description = "Homepage service URL";
};
};
}
);
default = [ ];
description = "Merged homepage service metadata contributed by repo modules.";
};
options.my.profiles.homepage = with lib; { options.my.profiles.homepage = with lib; {
enable = mkEnableOption "getHomepage.dev Dashboard"; enable = mkEnableOption "getHomepage.dev Dashboard";
}; };
@@ -16,13 +76,17 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.homepage-dashboard = { services.homepage-dashboard = {
enable = true; enable = true;
allowedHosts = "jupiter.solar.internal:8082"; listenPort = dashboardPort;
bookmarks = builtins.readFile ./bookmarks.yaml; allowedHosts = "${dashboardHost}:${toString dashboardPort},localhost:${toString dashboardPort},127.0.0.1:${toString dashboardPort}";
bookmarks = import ./bookmarks.nix;
services = homepageServices;
}; };
users.users.finn.packages = with pkgs; [ users.users.finn.packages = with pkgs; [
homepage-dashboard homepage-dashboard
]; ];
programs.chromium.homepageLocation = "http://jupiter.solar.internal:8082";
programs.chromium.homepageLocation = dashboardUrl;
}; };
} }
+11
View File
@@ -7,6 +7,8 @@
}: }:
let let
cfg = config.my.profiles.jellyfin; cfg = config.my.profiles.jellyfin;
hostName = config.networking.hostName;
port = 8096;
in in
{ {
options.my.profiles.jellyfin = with lib; { options.my.profiles.jellyfin = with lib; {
@@ -20,6 +22,15 @@ in
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Jellyfin";
description = "Media server";
href = "http://${hostName}:${toString port}";
}
];
systemd.services.jellyfin = { systemd.services.jellyfin = {
after = [ "network-online.target" ]; after = [ "network-online.target" ];
}; };
+11 -1
View File
@@ -2,7 +2,8 @@
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.profiles.jellyseerr; cfg = config.my.profiles.jellyseerr;
inherit (config.networking) domain; hostName = config.networking.hostName;
port = 5055;
in in
{ {
options.my.profiles.jellyseerr = with lib; { options.my.profiles.jellyseerr = with lib; {
@@ -15,6 +16,15 @@ in
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Jellyseerr";
description = "Media requests";
href = "http://${hostName}:${toString port}";
}
];
systemd.services.jellyseerr = { systemd.services.jellyseerr = {
after = [ "network-online.target" ]; after = [ "network-online.target" ];
}; };
@@ -2,6 +2,7 @@
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.profiles.paperless; cfg = config.my.profiles.paperless;
hostName = config.networking.hostName;
in in
{ {
options.my.profiles.paperless = with lib; { options.my.profiles.paperless = with lib; {
@@ -31,6 +32,16 @@ in
port = cfg.port; port = cfg.port;
# settings = cfg.extraConfig; # settings = cfg.extraConfig;
}; };
my.homepage.services = [
{
group = "Documents";
name = "Paperless";
description = "Document management";
href = "http://${hostName}:${toString cfg.port}";
}
];
networking.firewall.allowedTCPPorts = [ cfg.port ]; networking.firewall.allowedTCPPorts = [ cfg.port ];
}; };
} }
+12
View File
@@ -7,6 +7,8 @@
}: }:
let let
cfg = config.my.profiles.prowlarr; cfg = config.my.profiles.prowlarr;
hostName = config.networking.hostName;
port = 9696;
in in
# domain = config.networking.domain; # domain = config.networking.domain;
# port = 9696; # port = 9696;
@@ -20,6 +22,16 @@ in
enable = true; enable = true;
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Prowlarr";
description = "Indexer manager";
href = "http://${hostName}:${toString port}";
}
];
# # ugly fix for service not having a homedirectory # # ugly fix for service not having a homedirectory
# users.users.prowlarr = { # users.users.prowlarr = {
# isSystemUser = true; # isSystemUser = true;
+11
View File
@@ -7,6 +7,8 @@
}: }:
let let
cfg = config.my.profiles.radarr; cfg = config.my.profiles.radarr;
hostName = config.networking.hostName;
port = 7878;
in in
# domain = config.networking.domain; # domain = config.networking.domain;
# port = 7878; # port = 7878;
@@ -22,6 +24,15 @@ in
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Radarr";
description = "Movie management";
href = "http://${hostName}:${toString port}";
}
];
my.profiles.prowlarr.enable = true; my.profiles.prowlarr.enable = true;
systemd.services.radarr = { systemd.services.radarr = {
+11
View File
@@ -7,6 +7,8 @@
}: }:
let let
cfg = config.my.profiles.readarr; cfg = config.my.profiles.readarr;
hostName = config.networking.hostName;
port = 8787;
in in
# domain = config.networking.domain; # domain = config.networking.domain;
# port = 7878; # port = 7878;
@@ -22,6 +24,15 @@ in
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Readarr";
description = "Book management";
href = "http://${hostName}:${toString port}";
}
];
my.profiles.prowlarr.enable = true; my.profiles.prowlarr.enable = true;
systemd.services.readarr = { systemd.services.readarr = {
+10 -1
View File
@@ -7,7 +7,7 @@
}: }:
let let
cfg = config.my.profiles.sonarr; cfg = config.my.profiles.sonarr;
# domain = config.networking.domain; hostName = config.networking.hostName;
port = 8989; port = 8989;
in in
{ {
@@ -22,6 +22,15 @@ in
openFirewall = true; openFirewall = true;
}; };
my.homepage.services = [
{
group = "Media";
name = "Sonarr";
description = "Series management";
href = "http://${hostName}:${toString port}";
}
];
my.profiles.prowlarr.enable = true; my.profiles.prowlarr.enable = true;
systemd.services.sonarr = { systemd.services.sonarr = {
-1
View File
@@ -2,7 +2,6 @@
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.services.vpn; cfg = config.my.services.vpn;
inherit (config.networking) domain;
in in
{ {
options.my.services.vpn = with lib; { options.my.services.vpn = with lib; {
+52
View File
@@ -19,6 +19,36 @@ let
for this virtual host. for this virtual host.
''; '';
}; };
homepage = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to expose this virtual host on homepage-dashboard.
'';
};
group = lib.mkOption {
type = lib.types.str;
default = "Web";
description = ''
Homepage service group for this virtual host.
'';
};
name = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Optional display name for homepage-dashboard. Defaults to the subdomain.
'';
};
description = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Optional homepage-dashboard description for this virtual host.
'';
};
};
port = lib.mkOption { port = lib.mkOption {
type = with lib.types; nullOr port; type = with lib.types; nullOr port;
default = null; default = null;
@@ -67,14 +97,18 @@ in
{ {
subdomain = "gitea"; subdomain = "gitea";
port = 8080; port = 8080;
homepage.description = "Git forge";
} }
{ {
subdomain = "dev"; subdomain = "dev";
root = "/var/www/dev"; root = "/var/www/dev";
homepage.description = "Static site";
} }
{ {
subdomain = "jellyfin"; subdomain = "jellyfin";
port = 8096; port = 8096;
homepage.group = "Media";
homepage.description = "Media server";
extraConfig = { extraConfig = {
locations."/socket" = { locations."/socket" = {
proxyPass = "http://localhost:8096/"; proxyPass = "http://localhost:8096/";
@@ -109,6 +143,24 @@ in
} }
]; ];
my.homepage.services = map (
vhost:
{
group = vhost.homepage.group;
name = if vhost.homepage.name != "" then vhost.homepage.name else vhost.subdomain;
description =
if vhost.homepage.description != "" then
vhost.homepage.description
else if vhost.root != null then
"Static site"
else if vhost.port != null then
"Reverse proxied service"
else
"Web service";
href = "https://${vhost.subdomain}.${domain}";
}
) (builtins.filter (vhost: vhost.homepage.enable) cfg.virtualHosts);
services = { services = {
nginx.enable = false; nginx.enable = false;
caddy = { caddy = {