Nix-Vibe public snapshot (squashed history)
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
# Homepage Dashboard — Adding Machines, Tabs & Services
|
||||
|
||||
This guide covers how to add new machines, tabs, and services to the **Homepage**
|
||||
dashboards on **homeserver-1** (and, by extension, any host that imports the
|
||||
Homepage module).
|
||||
|
||||
## Overview
|
||||
|
||||
Homepage (https://gethomepage.dev) is a self-hosted dashboard. All dashboard
|
||||
configuration lives in Nix and is rendered to YAML files that Homepage reads
|
||||
at `/etc/homepage-dashboard/`.
|
||||
|
||||
| Item | Location |
|
||||
|------|----------|
|
||||
| Homepage NixOS module (service wrapper) | `modules/services/homepage.nix` |
|
||||
| Dashboard definition for homeserver-1 | `hosts/homeserver-1/homepage.nix` |
|
||||
| Deployed config files | `/etc/homepage-dashboard/{settings,services,widgets}.yaml` |
|
||||
| API keys / secrets | `secrets.yaml` (SOPS) → `HOMEPAGE_VAR_*` env vars |
|
||||
|
||||
The dashboard definition is split from the host config so it's easy to edit:
|
||||
|
||||
- `hosts/homeserver-1/configuration.nix` enables Glances + firewall and imports:
|
||||
```nix
|
||||
imports = [
|
||||
# ...
|
||||
./homepage.nix
|
||||
];
|
||||
```
|
||||
|
||||
## Applying Changes
|
||||
|
||||
After editing `homepage.nix`:
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch --target-host petere@homeserver-1 --flake .#homeserver-1 --use-remote-sudo
|
||||
```
|
||||
|
||||
> **Important:** Homepage reads its config files when the service starts. After
|
||||
> a `nixos-rebuild`, the unit's definition usually changes, but if only the
|
||||
> *contents* of the config files changed (e.g. just editing `homepage.nix`), the
|
||||
> service may keep the old config in memory. If your changes don't appear, restart it:
|
||||
>
|
||||
> ```bash
|
||||
> ssh petere@homeserver-1 "sudo systemctl restart homepage-dashboard"
|
||||
> ```
|
||||
|
||||
## Structure of the Dashboard Definition
|
||||
|
||||
`hosts/homeserver-1/homepage.nix` has three main parts:
|
||||
|
||||
```nix
|
||||
services.homepage = {
|
||||
enable = true;
|
||||
port = 8082;
|
||||
allowedHosts = [ ... ]; # Host header values Homepage responds to
|
||||
environmentFiles = [ ... ]; # SOPS-secret env file with HOMEPAGE_VAR_* keys
|
||||
|
||||
settings = {
|
||||
title = "HomeServer";
|
||||
# ...
|
||||
layout = { ... }; # Controls grouping, tabs, and column widths
|
||||
};
|
||||
|
||||
services = [ ... ]; # The service groups and tiles (services.yaml)
|
||||
widgets = [ ... ]; # Header info widgets (resources, search, clock)
|
||||
};
|
||||
```
|
||||
|
||||
## Tabs
|
||||
|
||||
Tabs are enabled by adding a `tab` field to a group's **layout** entry.
|
||||
|
||||
- Groups with the **same** `tab` value appear on that tab.
|
||||
- Groups with **no** `tab` appear on **every** tab.
|
||||
- Tabs are sorted by their order in the `layout` block.
|
||||
- Each tab is deep-linkable: `#monitoring`, `#homeserver-1`, etc.
|
||||
|
||||
Current tabs:
|
||||
|
||||
```
|
||||
Monitoring (default tab)
|
||||
├── Homeserver-1 Monitoring → 5 Glances tiles (localhost)
|
||||
└── MCF Server Monitoring → 5 Glances tiles (mcf-server via tailnet)
|
||||
|
||||
Homeserver-1 (#homeserver-1)
|
||||
├── Media → Jellyfin, Immich
|
||||
└── System → Backrest, Pocket ID, Tailscale
|
||||
|
||||
MCF Server (reserved; uncomment the placeholder to enable)
|
||||
```
|
||||
|
||||
## Adding a Service
|
||||
|
||||
1. **Add the service tile** to the relevant group in the `services` list:
|
||||
|
||||
```nix
|
||||
services = [
|
||||
# ...
|
||||
{
|
||||
System = [
|
||||
# ...existing tiles...
|
||||
{
|
||||
MyService = {
|
||||
icon = "sh-myservice";
|
||||
href = "http://homeserver-1.gerbil-opah.ts.net:<port>";
|
||||
description = "What it does";
|
||||
siteMonitor = "http://127.0.0.1:<port>"; # green/red status
|
||||
widget = { # optional live stats
|
||||
type = "myservice";
|
||||
url = "http://127.0.0.1:<port>";
|
||||
key = "{{HOMEPAGE_VAR_MYSERVICE_API_KEY}}"; # only if it needs a key
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
2. **Set the layout** so the group renders where you want (columns = how many
|
||||
tiles per row; groups span the full width with `style = "row"` when they're
|
||||
a single top-level group):
|
||||
|
||||
```nix
|
||||
layout = {
|
||||
# ...
|
||||
MyService = { # or add to an existing group's entry
|
||||
tab = "Homeserver-1";
|
||||
style = "row";
|
||||
columns = 4;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
3. **API keys**: never hardcode secrets. Add the value to `secrets.yaml` under
|
||||
the machine section and reference it via the environment file. The secret
|
||||
`homeserver-1/homepage-env` already provides `HOMEPAGE_VAR_JELLYFIN_API_KEY`,
|
||||
`HOMEPAGE_VAR_IMMICH_API_KEY`, `HOMEPAGE_VAR_TAILSCALE_API_KEY` and
|
||||
`HOMEPAGE_VAR_TAILSCALE_DEVICEID`. To add another:
|
||||
|
||||
```bash
|
||||
sops --set '["homeserver-1"]["homepage-env"] "HOMEPAGE_VAR_MYSERVICE_API_KEY=<value>"' secrets.yaml
|
||||
```
|
||||
|
||||
(This replaces the whole env file — include every existing `HOMEPAGE_VAR_*`
|
||||
line when setting it.)
|
||||
|
||||
## Adding a Tab
|
||||
|
||||
Add a new group to `services` and give it a `tab` in the layout:
|
||||
|
||||
```nix
|
||||
# services
|
||||
{
|
||||
"My New Group" = [
|
||||
{ "MyService" = { href = "..."; }; }
|
||||
];
|
||||
}
|
||||
|
||||
# layout
|
||||
"My New Group" = {
|
||||
tab = "My Tab";
|
||||
style = "row";
|
||||
columns = 4;
|
||||
};
|
||||
```
|
||||
|
||||
## Adding a New Machine to the Dashboard
|
||||
|
||||
To monitor another machine (e.g. `richmond-server`):
|
||||
|
||||
### 1. Enable Glances on the target machine
|
||||
|
||||
Add to that host's `configuration.nix` (Glances exposes system stats to the
|
||||
dashboard):
|
||||
|
||||
```nix
|
||||
services.glances = {
|
||||
enable = true;
|
||||
port = 61208;
|
||||
extraArgs = [ "--webserver" ];
|
||||
};
|
||||
|
||||
# Expose on Tailscale only
|
||||
networking.firewall.interfaces.tailscale.allowedTCPPorts = [ 61208 ];
|
||||
```
|
||||
|
||||
### 2. Add the monitoring group
|
||||
|
||||
In `hosts/homeserver-1/homepage.nix`, add a group with Glances tiles. **The
|
||||
group name must be unique** — Homepage's widget proxy resolves widget config by
|
||||
leaf group name, so duplicate group names cause one machine's stats to display
|
||||
on another's tiles.
|
||||
|
||||
```nix
|
||||
# services
|
||||
{
|
||||
"Richmond Server Monitoring" = [
|
||||
{ "System" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "info"; }; }; }
|
||||
{ "CPU" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "cpu"; }; }; }
|
||||
{ "Memory" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "memory"; }; }; }
|
||||
{ "Disk" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "fs:/"; }; }; }
|
||||
{ "Processes" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "process"; }; }; }
|
||||
];
|
||||
}
|
||||
|
||||
# layout
|
||||
"Richmond Server Monitoring" = {
|
||||
tab = "Monitoring";
|
||||
style = "row";
|
||||
columns = 5;
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Add non-monitoring services for that machine
|
||||
|
||||
Add a group and give it its own tab (or reuse an existing one):
|
||||
|
||||
```nix
|
||||
# services
|
||||
{
|
||||
"Richmond Server Apps" = [
|
||||
{ "Ntfy" = { icon = "sh-ntfy"; href = "http://richmond-server.gerbil-opah.ts.net:8080"; }; }
|
||||
];
|
||||
}
|
||||
|
||||
# layout
|
||||
"Richmond Server Apps" = {
|
||||
tab = "Richmond Server";
|
||||
style = "row";
|
||||
columns = 4;
|
||||
};
|
||||
```
|
||||
|
||||
### 4. (Optional) Tailscale widget for the machine
|
||||
|
||||
Each machine's Tailscale node can be shown with its own widget, using the
|
||||
machine's numeric device ID (find it via the Tailscale API/admin console):
|
||||
|
||||
```nix
|
||||
{
|
||||
"Richmond Server" = [
|
||||
{
|
||||
Tailscale = {
|
||||
icon = "sh-tailscale";
|
||||
href = "https://login.tailscale.com/admin/machines";
|
||||
widget = {
|
||||
type = "tailscale";
|
||||
deviceid = "<numeric-device-id>"; # NOT the ...CNTRL value
|
||||
key = "{{HOMEPAGE_VAR_TAILSCALE_API_KEY}}";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause / Fix |
|
||||
|---------|-------------|
|
||||
| Changes not appearing | Service not restarted — run `sudo systemctl restart homepage-dashboard` |
|
||||
| `t.metric is undefined` | Glances widget missing the `metric` field — every glances tile needs `metric` (e.g. `cpu`, `memory`, `fs:/`, `process`, `info`) |
|
||||
| `no manageable device matching this ID found` | Tailscale widget `deviceid` is wrong — must be the **numeric** device ID, not the `...CNTRL` value |
|
||||
| Two machines show the same stats | Duplicate group names — every group (especially monitoring) needs a unique name |
|
||||
| `Host validation failed` | The `Host` header isn't in `allowedHosts` — add the hostname (with port) to `allowedHosts` |
|
||||
| API keys showing in config | Keys must come from the SOPS env file (`HOMEPAGE_VAR_*`), never hardcoded |
|
||||
|
||||
## Glances Metrics
|
||||
|
||||
The Glances widget (`type = "glances"`) requires a `version` and `metric`:
|
||||
|
||||
- `version = 4` for Glances v4.x (installed)
|
||||
- `metric`: `info` (system summary), `cpu`, `memory`, `process`, `containers`,
|
||||
`fs:/` (disk usage), `network:<iface>`, `sensor:<id>`, `disk:<id>`, `gpu:<id>`
|
||||
Reference in New Issue
Block a user