diff --git a/hosts/freun-dev/glance.nix b/hosts/freun-dev/glance.nix new file mode 100644 index 0000000..24ff43a --- /dev/null +++ b/hosts/freun-dev/glance.nix @@ -0,0 +1,339 @@ +{ config, ... }: +let + secrets = config.age.secrets; +in +{ + services.tailscaledGlance = { + enable = true; + subdomain = "glance"; + settings = { + server.port = 4114; + pages = [ + { + name = "Home"; + columns = [ + { + size = "small"; + widgets = [ + { + type = "clock"; + hour-format = "24h"; + timezones = [ + { + timezone = "Europe/Zurich"; + label = "Zürich"; + } + ]; + } + { + type = "group"; + title = "Weather"; + widgets = + let + buildWeatherWidget = + { location, title }: + { + type = "weather"; + hide-location = true; + hour-format = "24h"; + units = "metric"; + inherit location title; + }; + in + builtins.map buildWeatherWidget [ + { + title = "Espoo"; + location = "Espoo, Finland"; + } + { + title = "Mökki"; + location = "Pellosniemi, Finland"; + } + { + title = "Frankfurt"; + location = "Frankfurt, Germany"; + } + ]; + } + { + type = "markets"; + markets = [ + { + symbol = "KOZ0.F"; + name = "Kongsberg Gruppen"; + } + { + symbol = "AMD"; + name = "AMD"; + } + ]; + } + { + type = "group"; + widgets = [ + { + type = "rss"; + title = "News"; + limit = 10; + collapse-after = 3; + cache = "12h"; + feeds = [ + { + url = "https://yle.fi/rss/uutiset/paauutiset"; + title = "Yle"; + } + ]; + } + { + type = "rss"; + title = "Tech"; + limit = 10; + collapse-after = 3; + cache = "12h"; + feeds = [ + { + url = "https://nixos.org/blog/announcements-rss.xml"; + title = "NixOS"; + } + { + url = "https://selfh.st/rss"; + title = "selfh.st"; + } + ]; + } + { + type = "rss"; + title = "Blogs"; + limit = 10; + collapse-after = 3; + cache = "12h"; + feeds = [ + { + url = "https://samharris.substack.com/feed"; + title = "Sam Harris"; + } + ]; + } + ]; + } + { + type = "custom-api"; + title = "Steam Specials"; + cache = "12h"; + url = "https://store.steampowered.com/api/featuredcategories?cc=fi"; + template = '' + + ''; + } + ]; + } + { + size = "full"; + widgets = [ + { + type = "group"; + widgets = [ + { type = "hacker-news"; } + { type = "lobsters"; } + ]; + } + { + type = "videos"; + channels = [ + "UCXuqSBlHAE6Xw-yeJA0Tunw" # Linus Tech Tips + "UCshObcm-nLhbu8MY50EZ5Ng" # Benn Jordan + ]; + } + { + type = "group"; + widgets = + let + type = "reddit"; + show-thumbnails = true; + app-auth = { + name = "Glance"; + id = { + _secret = secrets."glance/reddit/app-id".path; + }; + secret = { + _secret = secrets."glance/reddit/app-secret".path; + }; + }; + in + [ + { + inherit type app-auth show-thumbnails; + subreddit = "nixos"; + } + { + inherit type app-auth show-thumbnails; + subreddit = "technology"; + } + { + inherit type app-auth show-thumbnails; + subreddit = "selfhosted"; + } + ]; + } + ]; + } + { + size = "small"; + widgets = [ + { + type = "server-stats"; + servers = [ + { + type = "local"; + name = "freun.dev"; + } + ]; + } + { + type = "group"; + title = "Services"; + widgets = + let + buildSite = + domain: + { + subdomain, + title, + alt-status-codes ? [ ], + }: + { + inherit title alt-status-codes; + url = "https://${subdomain}.${domain}"; + }; + buildMonitor = + { domain, sites }: + { + type = "monitor"; + cache = "1m"; + title = domain; + style = "compact"; + sites = builtins.map (buildSite domain) sites; + }; + in + builtins.map buildMonitor [ + { + domain = "freun.dev"; + sites = [ + { + subdomain = "img"; + title = "Immich"; + } + { + subdomain = "pw"; + title = "Vaultwarden"; + } + { + subdomain = "social"; + title = "Gotosocial"; + } + { + subdomain = "graph"; + title = "Grafana"; + } + { + subdomain = "home"; + title = "Home Assistant"; + } + { + subdomain = "cook"; + title = "Mealie"; + } + { + subdomain = "sync"; + title = "Syncthing"; + } + { + subdomain = "bin"; + title = "Hastebin"; + alt-status-codes = [ 404 ]; + } + { + subdomain = "ledger"; + title = "Ledger"; + } + { + subdomain = "note"; + title = "Dnote"; + } + { + subdomain = "trackmap"; + title = "Trackmap"; + } + { + subdomain = "fit"; + title = "Workout Tracker"; + } + { + subdomain = "stream"; + title = "Owncast"; + } + { + subdomain = "read"; + title = "Readeck"; + } + ]; + } + { + domain = "alderaan.space"; + sites = [ + { + subdomain = "jelly"; + title = "Jellyfin"; + } + { + subdomain = "radarr"; + title = "Radarr"; + } + { + subdomain = "sonarr"; + title = "Sonarr"; + } + { + subdomain = "deluge"; + title = "qBittorrent"; + } + { + subdomain = "lidarr"; + title = "Lidarr"; + } + { + subdomain = "bazarr"; + title = "Bazarr"; + } + { + subdomain = "req"; + title = "Jellyseer"; + } + ]; + } + ]; + } + { + type = "dns-stats"; + service = "adguard"; + url = "http://localhost:3006"; + } + ]; + } + ]; + } + ]; + }; + }; +} diff --git a/hosts/freun-dev/secrets.nix b/hosts/freun-dev/secrets.nix index 1874cc4..b1a3019 100644 --- a/hosts/freun-dev/secrets.nix +++ b/hosts/freun-dev/secrets.nix @@ -25,6 +25,8 @@ "mosquitto/mokkimaatti" "gitlab-runner/default" "gitlab-runner/docker" + "glance/reddit/app-id" + "glance/reddit/app-secret" "hetzner" ] ) diff --git a/hosts/freun-dev/services.nix b/hosts/freun-dev/services.nix index d0f87d0..c5fc6cf 100644 --- a/hosts/freun-dev/services.nix +++ b/hosts/freun-dev/services.nix @@ -18,6 +18,9 @@ let secrets = config.age.secrets; in { + imports = [ + ./glance.nix + ]; virtualisation.podman.enable = true; virtualisation.oci-containers.backend = "podman"; security.acme.defaults.environmentFile = secrets.hetzner.path; diff --git a/modules/services/default.nix b/modules/services/default.nix index 16ddd5d..ae41162 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -25,5 +25,6 @@ ./home-assistant.nix ./weechat.nix ./hledger-web.nix + ./glance.nix ]; } diff --git a/modules/services/glance.nix b/modules/services/glance.nix new file mode 100644 index 0000000..4d0ee95 --- /dev/null +++ b/modules/services/glance.nix @@ -0,0 +1,45 @@ +{ config, lib, ... }: +let + cfg = config.services.tailscaledGlance; + fqdn = "${cfg.subdomain}.${config.networking.domain}"; + acme = config.security.acme; +in +{ + imports = [ + (lib.mkAliasOptionModule + [ "services" "tailscaledGlance" "settings" ] + [ "services" "glance" "settings" ] + ) + ]; + + options.services.tailscaledGlance = { + enable = lib.mkEnableOption "Enable tailscaled glance"; + subdomain = lib.mkOption { + type = lib.types.str; + }; + }; + + config = lib.mkIf cfg.enable { + services.tailscale.enable = true; + modules.firewall.interfaces.${config.services.tailscale.interfaceName} = [ "dns" ]; + + systemd.services.glance.serviceConfig.LoadCredential = [ + "fullchain.pem:${acme.certs.${fqdn}.directory}/fullchain.pem" + "key.pem:${acme.certs.${fqdn}.directory}/key.pem" + ]; + + services.glance = { + enable = cfg.enable; + }; + + systemd.services.glance = { + requires = [ "tailscaled.service" ]; + after = [ "tailscaled.service" ]; + }; + + services.webserver.vHosts.${fqdn} = { + tailscaleAuth = true; + locations."/".proxyPort = cfg.settings.server.port; + }; + }; +} diff --git a/secrets/glance/reddit/app-id.age b/secrets/glance/reddit/app-id.age new file mode 100644 index 0000000..3e9608b --- /dev/null +++ b/secrets/glance/reddit/app-id.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 osOCZA Y7ieflWxf67Jik747FnOu5aKcDjh6hd8OWE88oX7gWc +aQavFEvcW30cer2DutpkfSkKk1NqGzPiP2bYL2MCv+Q +-> ssh-ed25519 DFiohQ J5HO9n4KTQ6cSBGHxrBHORvmYp4WYJZiATekbZvhuEU +QGAhwn6P5ByiNY8bMUI07hHvnA8diVI56Vg+6kVEJb0 +-> ssh-ed25519 PT7ffg RpcpdzFtX5VyodX3lXKvjMRxMlpasRqqpjqCacXDcy4 +VJQuB8YfhB0DQ4TjwzBhdtl35eyFVLLW8O87mCuH828 +--- qJnfQgOyw0CTBhXNSyIw3O33av2cjPxTntLsOW/bevA +- 8^$-I4EJ5R ssh-ed25519 osOCZA y1DrZWN4jrO6xg7TkFqrjTT/k4L49IAZVf/NLw3jMiM +BB+Aq/80SFQpLJfZxRKFPBw9ylHb+Y6LLuZQAqG3WdQ +-> ssh-ed25519 DFiohQ jPPM8ATBvlXn0F/9pDCsZB15yW+af0b2FQqV2gI8YyQ +8yJjKEvEGKDwtvBWP/yjiDql+HA6l5q+RfEgP8cAIGM +-> ssh-ed25519 PT7ffg +R5KlrnH2gGW2Qc3V+RgYKtAXerbRB5j898+b41/VAU +7Lq3GE9CMGeXAmsf9WgSiJf/o+HyssF4xz94JNjbEgM +--- k2xNMbWr5tntlbOOYLbt6DsWsW2mT/P3pg3IgXYcM58 +|Ѱm7yzRY+q1>Y?hH֞|7̃ +Nz \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index bada010..d18d5c6 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -37,4 +37,6 @@ in ]; "hledger-basic-auth.age".publicKeys = users ++ [ freun-dev ]; "wpa_supplicant.age".publicKeys = users ++ [ turny ]; + "glance/reddit/app-id.age".publicKeys = users ++ [ freun-dev ]; + "glance/reddit/app-secret.age".publicKeys = users ++ [ freun-dev ]; }