manatee: Add services homepage with auto-discovery
Add a homepage module that generates a static landing page served on port 80 via nginx. Each service module registers itself via the shared mod.homepage.services option, so enabling a module automatically adds it to the page.
This commit is contained in:
@@ -10,6 +10,12 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [{
|
||||
name = "Audiobookshelf";
|
||||
port = 8000;
|
||||
description = "Audiobooks & podcasts";
|
||||
}];
|
||||
|
||||
users.users.audiobookshelf = {
|
||||
isSystemUser = true;
|
||||
description = "audiobookshelf";
|
||||
|
||||
@@ -10,6 +10,12 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [{
|
||||
name = "Calibre-Web";
|
||||
port = 8083;
|
||||
description = "E-book library";
|
||||
}];
|
||||
|
||||
services = {
|
||||
calibre-web = {
|
||||
enable = true;
|
||||
|
||||
@@ -22,6 +22,7 @@ in
|
||||
immich.enable = true;
|
||||
navidrome.enable = true;
|
||||
komga.enable = true;
|
||||
homepage.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
109
hosts/manatee/modules/homepage/default.nix
Normal file
109
hosts/manatee/modules/homepage/default.nix
Normal file
@@ -0,0 +1,109 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
enabled = config.mod.homepage.enable;
|
||||
nginxEnabled = config.mod.nginx.enable;
|
||||
services = config.mod.homepage.services;
|
||||
|
||||
serviceToCard = svc: ''
|
||||
<a class="card" href="http://manatee:${toString svc.port}">
|
||||
<div class="name">${svc.name}</div>
|
||||
<div class="desc">${svc.description}</div>
|
||||
<div class="port">:${toString svc.port}</div>
|
||||
</a>
|
||||
'';
|
||||
|
||||
page = pkgs.writeTextDir "index.html" ''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>manatee</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background: #1a1b26;
|
||||
color: #c0caf5;
|
||||
min-height: 100vh;
|
||||
padding: 3rem 1.5rem;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
color: #7aa2f7;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.card {
|
||||
display: block;
|
||||
background: #24283b;
|
||||
border: 1px solid #414868;
|
||||
border-radius: 8px;
|
||||
padding: 1.25rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
.card:hover { border-color: #7aa2f7; }
|
||||
.name { font-size: 1.1rem; font-weight: 600; color: #c0caf5; }
|
||||
.desc { font-size: 0.85rem; color: #565f89; margin-top: 0.35rem; }
|
||||
.port { font-size: 0.8rem; color: #414868; margin-top: 0.5rem; font-family: monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>manatee</h1>
|
||||
<div class="grid">
|
||||
${lib.concatMapStrings serviceToCard services}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'';
|
||||
in
|
||||
{
|
||||
options = {
|
||||
mod.homepage = {
|
||||
enable = lib.mkEnableOption "Enable homepage module";
|
||||
services = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.submodule {
|
||||
options = {
|
||||
name = lib.mkOption { type = lib.types.str; };
|
||||
port = lib.mkOption { type = lib.types.port; };
|
||||
description = lib.mkOption { type = lib.types.str; };
|
||||
};
|
||||
});
|
||||
default = [ ];
|
||||
description = "Services to display on the homepage";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (enabled && nginxEnabled) {
|
||||
services.nginx.virtualHosts."homepage" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 9999;
|
||||
}
|
||||
];
|
||||
root = page;
|
||||
locations."/" = {
|
||||
index = "index.html";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 9999 ];
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,12 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [{
|
||||
name = "Immich";
|
||||
port = 2283;
|
||||
description = "Photo library";
|
||||
}];
|
||||
|
||||
users.users.immich = {
|
||||
isSystemUser = true;
|
||||
group = "storage";
|
||||
|
||||
@@ -47,6 +47,12 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
mod.homepage.services = [{
|
||||
name = "Jellyfin";
|
||||
port = 8096;
|
||||
description = "Media streaming";
|
||||
}];
|
||||
|
||||
networking = {
|
||||
firewall.allowedTCPPorts = [ 8096 ];
|
||||
};
|
||||
|
||||
@@ -19,6 +19,19 @@ in
|
||||
imports = [ inputs.komga-comictracker.nixosModules.default ];
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [
|
||||
{
|
||||
name = "Komga";
|
||||
port = 8002;
|
||||
description = "Comic library";
|
||||
}
|
||||
{
|
||||
name = "Komga Reader";
|
||||
port = 8888;
|
||||
description = "Comic reader";
|
||||
}
|
||||
];
|
||||
|
||||
users.users.komga = {
|
||||
isSystemUser = true;
|
||||
group = "storage";
|
||||
|
||||
@@ -15,6 +15,12 @@ in
|
||||
};
|
||||
|
||||
config = {
|
||||
mod.homepage.services = lib.mkIf navidromeEnabled [{
|
||||
name = "Navidrome";
|
||||
port = 4533;
|
||||
description = "Music streaming";
|
||||
}];
|
||||
|
||||
services = lib.mkIf navidromeEnabled {
|
||||
navidrome = {
|
||||
enable = true;
|
||||
|
||||
@@ -10,6 +10,12 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [{
|
||||
name = "Syncthing";
|
||||
port = 8384;
|
||||
description = "File sync";
|
||||
}];
|
||||
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
|
||||
|
||||
@@ -15,6 +15,12 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf enabled {
|
||||
mod.homepage.services = [{
|
||||
name = "Transmission";
|
||||
port = 9091;
|
||||
description = "Torrent client";
|
||||
}];
|
||||
|
||||
services = {
|
||||
transmission = {
|
||||
enable = true;
|
||||
|
||||
Reference in New Issue
Block a user