freun.dev: add glance

This commit is contained in:
Joakim Repomaa
2025-07-23 20:04:03 +03:00
parent fa02a302dc
commit 8774faa201
8 changed files with 411 additions and 0 deletions

339
hosts/freun-dev/glance.nix Normal file
View File

@@ -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 = ''
<ul class="list list-gap-10 collapsible-container" data-collapse-after="5">
{{ range .JSON.Array "specials.items" }}
<li>
<a class="size-h4 color-highlight block text-truncate" href="https://store.steampowered.com/app/{{ .Int "id" }}/">{{ .String "name" }}</a>
<ul class="list-horizontal-text">
<li>{{ div (.Int "final_price" | toFloat) 100 | printf "$%.2f" }}</li>
{{ $discount := .Int "discount_percent" }}
<li{{ if ge $discount 40 }} class="color-positive"{{ end }}>{{ $discount }}% off</li>
</ul>
</li>
{{ end }}
</ul>
'';
}
];
}
{
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";
}
];
}
];
}
];
};
};
}

View File

@@ -25,6 +25,8 @@
"mosquitto/mokkimaatti"
"gitlab-runner/default"
"gitlab-runner/docker"
"glance/reddit/app-id"
"glance/reddit/app-secret"
"hetzner"
]
)

View File

@@ -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;

View File

@@ -25,5 +25,6 @@
./home-assistant.nix
./weechat.nix
./hledger-web.nix
./glance.nix
];
}

View File

@@ -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;
};
};
}

View File

@@ -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
-åž

View File

@@ -0,0 +1,10 @@
age-encryption.org/v1
-> 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
|ìÍѰm7Æy‰z¡¥R©ÔíYê+qî§ü—1>ž‡Y?hHÖžÌÌÈ|ù7àÞþ̃
N¥zÚöØäëøð

View File

@@ -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 ];
}