* feat: warning for adguard schema mismatch * Auto lint/format * fix: fix filtering * chore: tweak automerge * fix: whoogle * hack * hax * hack * feat: clean tmp on boot * M E G A H A C K * derp lel * chore: name * feat: add shodan! --------- Co-authored-by: Truxnell <9149206+truxnell@users.noreply.github.com> Co-authored-by: truxnell <truxnell@users.noreply.github.com>
322 lines
9.2 KiB
Nix
322 lines
9.2 KiB
Nix
{ lib
|
|
, config
|
|
, pkgs
|
|
, self
|
|
, ...
|
|
}:
|
|
with lib;
|
|
let
|
|
app = "homepage";
|
|
image = "ghcr.io/gethomepage/homepage:v0.8.11";
|
|
user = "568"; #string
|
|
group = "568"; #string
|
|
port = 3000; #int
|
|
cfg = config.mySystem.services.${app};
|
|
appFolder = "containers/${app}";
|
|
persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}";
|
|
|
|
# TODO refactor out this sht
|
|
settings =
|
|
{
|
|
title = "NatFlix";
|
|
theme = "dark";
|
|
color = "slate";
|
|
showStats = true;
|
|
disableCollape = true;
|
|
cardBlur = "md";
|
|
statusStyle = "none";
|
|
|
|
datetime = {
|
|
text_size = "l";
|
|
format = {
|
|
timeStyle = "short";
|
|
dateStyle = "short";
|
|
hourCycle = "h23";
|
|
};
|
|
};
|
|
|
|
providers = {
|
|
openweathermap = "{{HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY}}";
|
|
};
|
|
};
|
|
|
|
settingsFile = builtins.toFile "homepage-settings.yaml" (builtins.toJSON settings);
|
|
|
|
bookmarks = [
|
|
{
|
|
Administration = [
|
|
{ Source = [{ icon = "github.png"; href = "https://github.com/truxnell/nix-config"; }]; }
|
|
{ Cloudflare = [{ icon = "cloudflare.png"; href = "https://dash.cloudflare.com/"; }]; }
|
|
];
|
|
}
|
|
{
|
|
Development = [
|
|
{ CyberChef = [{ icon = "cyberchef.png"; href = "https://gchq.github.io/CyberChef/"; }]; }
|
|
{ "Nix Options Search" = [{ abbr = "NS"; href = "https://search.nixos.org/packages"; }]; }
|
|
{ "Doppler Secrets" = [{ abbr = "DP"; href = "https://dashboard.doppler.com"; }]; }
|
|
{ "onedr0p Containers" = [{ abbr = "OC"; href = "https://github.com/onedr0p/containers"; }]; }
|
|
{ "bjw-s Containers" = [{ abbr = "BC"; href = "https://github.com/bjw-s/container-images"; }]; }
|
|
|
|
];
|
|
}
|
|
];
|
|
bookmarksFile = builtins.toFile "homepage-bookmarks.yaml" (builtins.toJSON bookmarks);
|
|
|
|
widgets = [
|
|
{
|
|
resources = {
|
|
cpu = true;
|
|
memory = true;
|
|
cputemp = true;
|
|
uptime = true;
|
|
disk = "/";
|
|
units = "metric";
|
|
# label = "system";
|
|
};
|
|
}
|
|
{
|
|
datetime = {
|
|
text_size = "l";
|
|
locale = "au";
|
|
format = {
|
|
timeStyle = "short";
|
|
dateStyle = "short";
|
|
hourCycle = "h23";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
openmeteo = {
|
|
label = "Melbourne";
|
|
latitude = "-37.8136";
|
|
longitude = "144.9631";
|
|
timezone = config.time.timeZone;
|
|
units = "metric";
|
|
cache = 5;
|
|
};
|
|
}
|
|
];
|
|
widgetsFile = builtins.toFile "homepage-widgets.yaml" (builtins.toJSON widgets);
|
|
|
|
extraInfrastructure = [
|
|
{
|
|
"UDMP" = {
|
|
href = "https://unifi.${config.mySystem.internalDomain}";
|
|
|
|
description = "Unifi Dream Machine Pro";
|
|
icon = "ubiquiti";
|
|
widget = {
|
|
url = "https://unifi.${config.mySystem.internalDomain}";
|
|
username = "unifi_read_only";
|
|
password = "{{HOMEPAGE_VAR_UNIFI_PASSWORD}}";
|
|
type = "unifi";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
"Nextdns" = {
|
|
href = "https://my.nextdns.io/";
|
|
description = "Adblocking DNS";
|
|
icon = "nextdns";
|
|
widget = {
|
|
profile = "{{HOMEPAGE_VAR_NEXTDNS_TRUSTED_PROFILE}}";
|
|
key = "{{HOMEPAGE_VAR_NEXTDNS_API_KEY}}";
|
|
type = "nextdns";
|
|
};
|
|
};
|
|
}
|
|
{
|
|
"Cloudflare" = {
|
|
href = "https://dash.cloudflare.com";
|
|
description = "DNS and security provider";
|
|
icon = "cloudflare";
|
|
widget = {
|
|
key = "{{HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_API}}";
|
|
accountid = "{{HOMEPAGE_VAR_CLOUDFLARE_ACCOUNT_ID}}";
|
|
tunnelid = "{{HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_ID}}";
|
|
type = "cloudflared";
|
|
};
|
|
};
|
|
}
|
|
|
|
];
|
|
|
|
extraHome = [
|
|
{
|
|
"Prusa Octoprint" = {
|
|
href = "http://prusa.${config.mySystem.internalDomain}:5000";
|
|
|
|
description = "Prusa MK3s 3D printer";
|
|
icon = "octoprint";
|
|
widget = {
|
|
type = "octoprint";
|
|
url = "http://prusa:5000";
|
|
key = "{{HOMEPAGE_VAR_PRUSA_OCTOPRINT_API}}";
|
|
};
|
|
};
|
|
}
|
|
];
|
|
|
|
services = [
|
|
{
|
|
Infrastructure = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.infrastructure-services)
|
|
(builtins.attrValues self.nixosConfigurations) ++ extraInfrastructure;
|
|
}
|
|
{
|
|
Home = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.home-services)
|
|
(builtins.attrValues self.nixosConfigurations) ++ extraHome;
|
|
}
|
|
{
|
|
Media = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.media-services)
|
|
(builtins.attrValues self.nixosConfigurations);
|
|
}
|
|
];
|
|
servicesFile = builtins.toFile "homepage-config.yaml" (builtins.toJSON services);
|
|
emptyFile = builtins.toFile "docker.yaml" (builtins.toJSON [{ }]);
|
|
|
|
in
|
|
{
|
|
options.mySystem.services.homepage = {
|
|
enable = mkEnableOption "Homepage dashboard";
|
|
infrastructure-services = lib.mkOption {
|
|
type = lib.types.listOf lib.types.attrs;
|
|
description = "Services to add to the infrastructure column";
|
|
default = [ ];
|
|
};
|
|
home-services = lib.mkOption {
|
|
type = lib.types.listOf lib.types.attrs;
|
|
description = "Services to add to the infrastructure column";
|
|
default = [ ];
|
|
};
|
|
media-services = lib.mkOption {
|
|
type = lib.types.listOf lib.types.attrs;
|
|
description = "Services to add to the infrastructure column";
|
|
default = [ ];
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
# homepage secrets
|
|
# ensure you dont have whitespace around your ='s!
|
|
# ex: HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_API=supersecretlol
|
|
sops.secrets."services/homepage/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ./secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
|
|
# api secrets from other apps
|
|
sops.secrets."services/sonarr/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ../arr/sonarr/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
sops.secrets."services/radarr/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ../arr/radarr/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
sops.secrets."services/lidarr/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ../arr/lidarr/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
sops.secrets."services/readarr/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ../arr/readarr/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
sops.secrets."services/prowlarr/env" = {
|
|
# configure secret for forwarding rules
|
|
sopsFile = ../arr/prowlarr/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
sops.secrets."services/adguardhome/env" = {
|
|
sopsFile = ../../services/adguardhome/secrets.sops.yaml;
|
|
owner = "kah";
|
|
group = "kah";
|
|
restartUnits = [ "podman-${app}.service" ];
|
|
};
|
|
|
|
|
|
virtualisation.oci-containers.containers.${app} = {
|
|
image = "${image}";
|
|
user = "${user}:${group}";
|
|
|
|
environment = {
|
|
UMASK = "002";
|
|
PUID = "${user}";
|
|
PGID = "${group}";
|
|
LOG_TARGETS = "stdout";
|
|
};
|
|
|
|
# secrets
|
|
environmentFiles = [
|
|
config.sops.secrets."services/homepage/env".path
|
|
|
|
config.sops.secrets."services/sonarr/env".path
|
|
config.sops.secrets."services/radarr/env".path
|
|
config.sops.secrets."services/readarr/env".path
|
|
config.sops.secrets."services/lidarr/env".path
|
|
config.sops.secrets."services/prowlarr/env".path
|
|
config.sops.secrets."services/adguardhome/env".path
|
|
|
|
];
|
|
|
|
# labels = {
|
|
# "traefik.enable" = "true";
|
|
# "traefik.http.routers.${app}.entrypoints" = "websecure";
|
|
# "traefik.http.routers.${app}.middlewares" = "local-ip-only@file";
|
|
# "traefik.http.services.${app}.loadbalancer.server.port" = "${toString port}";
|
|
# };
|
|
labels = lib.myLib.mkTraefikLabels {
|
|
name = app;
|
|
domain = config.networking.domain;
|
|
|
|
inherit port;
|
|
};
|
|
# not using docker socket for discovery, just
|
|
# building up the apps from a shared key
|
|
# this is a bit more tedious, but more secure
|
|
# from not exposing docker socet and makes it
|
|
# easier to have/move services between hosts
|
|
volumes = [
|
|
"/etc/localtime:/etc/localtime:ro"
|
|
"${settingsFile}:/app/config/settings.yaml:ro"
|
|
"${servicesFile}:/app/config/services.yaml:ro"
|
|
"${bookmarksFile}:/app/config/bookmarks.yaml:ro"
|
|
"${widgetsFile}:/app/config/widgets.yaml:ro"
|
|
"${emptyFile}:/app/config/docker.yaml:ro"
|
|
"${emptyFile}:/app/config/kubernetes.yaml:ro"
|
|
];
|
|
|
|
extraOptions = [
|
|
"--read-only"
|
|
"--tmpfs=/app/config"
|
|
];
|
|
};
|
|
|
|
mySystem.services.gatus.monitors = [{
|
|
name = app;
|
|
group = "infrastructure";
|
|
url = "https://${app}.${config.mySystem.domain}";
|
|
interval = "1m";
|
|
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
|
|
}];
|
|
|
|
|
|
};
|
|
}
|