Decommission Homepage dashboard and update history hooks
This commit is contained in:
parent
7145a35927
commit
02382f8446
10 changed files with 3 additions and 359 deletions
|
|
@ -58,7 +58,7 @@ let
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
post = "nvd diff $OLD_SYSTEM /run/current-system && (command -v record-update &>/dev/null && record-update $OLD_SYSTEM /run/current-system || true)";
|
post = "nvd diff $OLD_SYSTEM /run/current-system";
|
||||||
|
|
||||||
# The server evaluates and builds for itself.
|
# The server evaluates and builds for itself.
|
||||||
localUpdate = if config.networking.hostName == "FredOS-Mediaserver"
|
localUpdate = if config.networking.hostName == "FredOS-Mediaserver"
|
||||||
|
|
@ -112,7 +112,6 @@ in
|
||||||
./services/bazarr-sync.nix
|
./services/bazarr-sync.nix
|
||||||
./services/cloudflare-ddns.nix
|
./services/cloudflare-ddns.nix
|
||||||
./services/authelia.nix
|
./services/authelia.nix
|
||||||
./services/homepage.nix
|
|
||||||
./services/arr-interconnect.nix
|
./services/arr-interconnect.nix
|
||||||
./services/profilarr.nix
|
./services/profilarr.nix
|
||||||
./services/shelfarr.nix
|
./services/shelfarr.nix
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,6 @@
|
||||||
export PATH="${pkgs.jellyfin-ffmpeg}/bin:${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gawk}/bin:${pkgs.bc}/bin:${pkgs.curl}/bin:$PATH"
|
export PATH="${pkgs.jellyfin-ffmpeg}/bin:${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gawk}/bin:${pkgs.bc}/bin:${pkgs.curl}/bin:$PATH"
|
||||||
exec ${pkgs.bash}/bin/bash ${../scripts/transcode-hevc.sh} "$@"
|
exec ${pkgs.bash}/bin/bash ${../scripts/transcode-hevc.sh} "$@"
|
||||||
'')
|
'')
|
||||||
(pkgs.writeShellScriptBin "record-update" ''
|
|
||||||
export PATH="${pkgs.nvd}/bin:${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:$PATH"
|
|
||||||
exec ${pkgs.bash}/bin/bash ${../scripts/record-update.sh} "$@"
|
|
||||||
'')
|
|
||||||
# Stats stream for the quickshell server monitor on the desktops:
|
# Stats stream for the quickshell server monitor on the desktops:
|
||||||
# `ssh mediaserver qs-stats` = top's 2s batch stream, interleaved with
|
# `ssh mediaserver qs-stats` = top's 2s batch stream, interleaved with
|
||||||
# one @STAT line per tick (hottest coretemp across both sockets, WAN
|
# one @STAT line per tick (hottest coretemp across both sockets, WAN
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ Flake-based NixOS configuration for three machines, built and deployed directly
|
||||||
│ ├── frigate.nix # NVR with object detection
|
│ ├── frigate.nix # NVR with object detection
|
||||||
│ ├── game-servers.nix # Dockerised 7 Days to Die servers
|
│ ├── game-servers.nix # Dockerised 7 Days to Die servers
|
||||||
│ ├── go2rtc.nix # Camera/RTSP streaming
|
│ ├── go2rtc.nix # Camera/RTSP streaming
|
||||||
│ ├── homepage.nix # Homepage dashboard with auto-extracted API keys
|
|
||||||
│ ├── jellyfin.nix # Media server
|
│ ├── jellyfin.nix # Media server
|
||||||
│ ├── memos.nix # Flatnotes notes app (container)
|
│ ├── memos.nix # Flatnotes notes app (container)
|
||||||
│ ├── nginx.nix # Reverse proxy + ACME wildcard cert via Cloudflare DNS-01
|
│ ├── nginx.nix # Reverse proxy + ACME wildcard cert via Cloudflare DNS-01
|
||||||
|
|
|
||||||
|
|
@ -98,22 +98,9 @@ class Fixture(m.Deployment):
|
||||||
self.healthy()
|
self.healthy()
|
||||||
|
|
||||||
def deploy(self, ident="a" * 32, flake="fixture", reboot=False):
|
def deploy(self, ident="a" * 32, flake="fixture", reboot=False):
|
||||||
with patch.object(
|
|
||||||
Path,
|
|
||||||
"exists",
|
|
||||||
autospec=True,
|
|
||||||
side_effect=lambda p: (
|
|
||||||
False
|
|
||||||
if str(p) == "/run/current-system/sw/bin/record-update"
|
|
||||||
else original_exists(p)
|
|
||||||
),
|
|
||||||
):
|
|
||||||
super().deploy(ident, flake, reboot)
|
super().deploy(ident, flake, reboot)
|
||||||
|
|
||||||
|
|
||||||
original_exists = Path.exists
|
|
||||||
|
|
||||||
|
|
||||||
class Transactions(unittest.TestCase):
|
class Transactions(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.temp = tempfile.TemporaryDirectory(prefix="fred-deploy-check-")
|
self.temp = tempfile.TemporaryDirectory(prefix="fred-deploy-check-")
|
||||||
|
|
|
||||||
|
|
@ -443,17 +443,6 @@ class Deployment:
|
||||||
flush=True,
|
flush=True,
|
||||||
)
|
)
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
recorder = Path("/run/current-system/sw/bin/record-update")
|
|
||||||
if recorder.exists():
|
|
||||||
try:
|
|
||||||
self.command(
|
|
||||||
[str(recorder), record["old_running"], candidate], timeout=30
|
|
||||||
)
|
|
||||||
except Exception as error:
|
|
||||||
print(
|
|
||||||
f"Deployment committed; history recording failed: {error}",
|
|
||||||
flush=True,
|
|
||||||
)
|
|
||||||
if reboot:
|
if reboot:
|
||||||
components = ("kernel", "initrd", "kernel-modules")
|
components = ("kernel", "initrd", "kernel-modules")
|
||||||
if any(
|
if any(
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Parse `nvd diff <old> <new>` output and write a JSON summary
|
|
||||||
# consumed by the Homepage dashboard's customapi widget.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
OLD="${1:-}"
|
|
||||||
NEW="${2:-/run/current-system}"
|
|
||||||
OUT_DIR="/var/lib/homepage-updates"
|
|
||||||
OUT_FILE="$OUT_DIR/latest.json"
|
|
||||||
|
|
||||||
if [ -z "$OLD" ]; then
|
|
||||||
echo "usage: record-update <old-system> [new-system]" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$OUT_DIR"
|
|
||||||
|
|
||||||
DIFF=$(nvd diff "$OLD" "$NEW" 2>&1 || true)
|
|
||||||
|
|
||||||
CHANGES=$(printf '%s\n' "$DIFF" | grep -cE '^\[[UAR][.*]\]' || true)
|
|
||||||
CLOSURE=$(printf '%s\n' "$DIFF" | grep -oE 'disk usage [+-][0-9.]+[A-Za-z]*B?' | head -1 | sed 's/disk usage //')
|
|
||||||
CLOSURE="${CLOSURE:-+0B}"
|
|
||||||
|
|
||||||
KERNEL=$(uname -r)
|
|
||||||
DATE=$(date '+%Y-%m-%d %H:%M')
|
|
||||||
|
|
||||||
if [ "$CHANGES" = "0" ]; then
|
|
||||||
LABEL="No changes"
|
|
||||||
else
|
|
||||||
LABEL="$CHANGES package changes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > "$OUT_FILE.tmp" <<EOF
|
|
||||||
{
|
|
||||||
"date": "$DATE",
|
|
||||||
"changes": "$LABEL",
|
|
||||||
"closure": "$CLOSURE",
|
|
||||||
"kernel": "$KERNEL"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
mv "$OUT_FILE.tmp" "$OUT_FILE"
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
rules = [
|
rules = [
|
||||||
{ domain = "frigate.nordhammer.it"; policy = "one_factor"; }
|
{ domain = "frigate.nordhammer.it"; policy = "one_factor"; }
|
||||||
{ domain = "camera.nordhammer.it"; policy = "one_factor"; }
|
{ domain = "camera.nordhammer.it"; policy = "one_factor"; }
|
||||||
{ domain = "homepage.nordhammer.it"; policy = "one_factor"; }
|
|
||||||
# { domain = "7dtd.nordhammer.it"; policy = "one_factor"; } # 7DTD disabled
|
# { domain = "7dtd.nordhammer.it"; policy = "one_factor"; } # 7DTD disabled
|
||||||
{ domain = "adguard.nordhammer.it"; policy = "one_factor"; }
|
{ domain = "adguard.nordhammer.it"; policy = "one_factor"; }
|
||||||
{ domain = "router.nordhammer.it"; policy = "one_factor"; }
|
{ domain = "router.nordhammer.it"; policy = "one_factor"; }
|
||||||
|
|
|
||||||
|
|
@ -1,273 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
let
|
|
||||||
# Script that extracts API keys from all services and writes /etc/homepage-secrets
|
|
||||||
extractSecrets = pkgs.writeShellScript "extract-homepage-secrets" ''
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SECRETS_FILE="/etc/homepage-secrets"
|
|
||||||
|
|
||||||
# --- *arr apps: API keys live in config.xml as <ApiKey>...</ApiKey> ---
|
|
||||||
extract_arr_key() {
|
|
||||||
local name="$1" path="$2"
|
|
||||||
if [ -f "$path" ]; then
|
|
||||||
${pkgs.gnused}/bin/sed -n 's/.*<ApiKey>\(.*\)<\/ApiKey>.*/\1/p' "$path"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
SONARR_KEY=$(extract_arr_key "sonarr" "/var/lib/sonarr/config.xml")
|
|
||||||
RADARR_KEY=$(extract_arr_key "radarr" "/var/lib/radarr/config.xml")
|
|
||||||
PROWLARR_KEY=$(extract_arr_key "prowlarr" "/var/lib/prowlarr/config.xml")
|
|
||||||
|
|
||||||
# --- Bazarr: API key in config.ini under [auth] section ---
|
|
||||||
BAZARR_KEY=""
|
|
||||||
if [ -f "/var/lib/bazarr/data/config/config.ini" ]; then
|
|
||||||
BAZARR_KEY=$(${pkgs.gnugrep}/bin/grep -oP '(?<=apikey = ).*' /var/lib/bazarr/data/config/config.ini || true)
|
|
||||||
fi
|
|
||||||
# Fallback: Bazarr sometimes stores it in config.yaml
|
|
||||||
if [ -z "$BAZARR_KEY" ] && [ -f "/var/lib/bazarr/config/config.yaml" ]; then
|
|
||||||
BAZARR_KEY=$(${pkgs.gnugrep}/bin/grep -oP '(?<=apikey: ).*' /var/lib/bazarr/config/config.yaml || true)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Jellyfin: create an API key in the DB if one doesn't exist ---
|
|
||||||
JELLYFIN_KEY=""
|
|
||||||
JELLYFIN_DB="/var/lib/jellyfin/data/jellyfin.db"
|
|
||||||
if [ -f "$JELLYFIN_DB" ]; then
|
|
||||||
# Check if a "Homepage" key already exists
|
|
||||||
JELLYFIN_KEY=$(${pkgs.sqlite}/bin/sqlite3 "$JELLYFIN_DB" \
|
|
||||||
"SELECT AccessToken FROM ApiKeys WHERE Name = 'Homepage' LIMIT 1;" 2>/dev/null || true)
|
|
||||||
|
|
||||||
if [ -z "$JELLYFIN_KEY" ]; then
|
|
||||||
# Generate a random 32-char hex token
|
|
||||||
JELLYFIN_KEY=$(${pkgs.coreutils}/bin/head -c 16 /dev/urandom | ${pkgs.coreutils}/bin/od -An -tx1 | ${pkgs.gnused}/bin/sed 's/ //g' | ${pkgs.coreutils}/bin/head -c 32)
|
|
||||||
NOW=$(${pkgs.coreutils}/bin/date -u '+%Y-%m-%d %H:%M:%S')
|
|
||||||
${pkgs.sqlite}/bin/sqlite3 "$JELLYFIN_DB" \
|
|
||||||
"INSERT INTO ApiKeys (DateCreated, DateLastActivity, Name, AccessToken) VALUES ('$NOW', '0001-01-01 00:01:00', 'Homepage', '$JELLYFIN_KEY');"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Write the secrets file ---
|
|
||||||
cat > "$SECRETS_FILE" <<EOF
|
|
||||||
HOMEPAGE_VAR_SONARR_KEY=$SONARR_KEY
|
|
||||||
HOMEPAGE_VAR_RADARR_KEY=$RADARR_KEY
|
|
||||||
HOMEPAGE_VAR_PROWLARR_KEY=$PROWLARR_KEY
|
|
||||||
HOMEPAGE_VAR_BAZARR_KEY=$BAZARR_KEY
|
|
||||||
HOMEPAGE_VAR_JELLYFIN_KEY=$JELLYFIN_KEY
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod 600 "$SECRETS_FILE"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/homepage-updates 0755 fred users -"
|
|
||||||
''f /var/lib/homepage-updates/latest.json 0644 fred users - {\x22date\x22:\x22pending\x22,\x22changes\x22:\x22run update\x22,\x22closure\x22:\x22+0B\x22,\x22kernel\x22:\x22-\x22}''
|
|
||||||
];
|
|
||||||
|
|
||||||
# Oneshot service that extracts API keys and writes /etc/homepage-secrets
|
|
||||||
systemd.services.homepage-extract-secrets = {
|
|
||||||
description = "Extract API keys for Homepage dashboard";
|
|
||||||
after = [
|
|
||||||
"jellyfin.service"
|
|
||||||
"sonarr.service"
|
|
||||||
"radarr.service"
|
|
||||||
"bazarr.service"
|
|
||||||
"prowlarr.service"
|
|
||||||
];
|
|
||||||
requires = [ "jellyfin.service" ];
|
|
||||||
before = [ "homepage-dashboard.service" ];
|
|
||||||
requiredBy = [ "homepage-dashboard.service" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = extractSecrets;
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.homepage-dashboard = {
|
|
||||||
enable = true;
|
|
||||||
listenPort = 8084;
|
|
||||||
|
|
||||||
# Allow access from anywhere on the LAN
|
|
||||||
allowedHosts = "localhost:8084,127.0.0.1:8084,homepage.nordhammer.it";
|
|
||||||
|
|
||||||
# API keys auto-extracted by homepage-extract-secrets.service
|
|
||||||
environmentFiles = [ "/etc/homepage-secrets" ];
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
title = "FredOS Mediaserver";
|
|
||||||
theme = "dark";
|
|
||||||
color = "slate";
|
|
||||||
headerStyle = "clean";
|
|
||||||
layout = {
|
|
||||||
Media = { style = "row"; columns = 2; };
|
|
||||||
Downloads = { style = "row"; columns = 2; };
|
|
||||||
Infrastructure = { style = "row"; columns = 3; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
resources = {
|
|
||||||
cpu = true;
|
|
||||||
memory = true;
|
|
||||||
disk = "/";
|
|
||||||
label = "System";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
search = {
|
|
||||||
provider = "duckduckgo";
|
|
||||||
target = "_blank";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
datetime = {
|
|
||||||
text_size = "xl";
|
|
||||||
format = {
|
|
||||||
timeStyle = "short";
|
|
||||||
dateStyle = "short";
|
|
||||||
hour12 = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
services = [
|
|
||||||
{
|
|
||||||
Media = [
|
|
||||||
{
|
|
||||||
Jellyfin = {
|
|
||||||
href = "https://jellyfin.nordhammer.it";
|
|
||||||
description = "Media server";
|
|
||||||
icon = "jellyfin.png";
|
|
||||||
widget = {
|
|
||||||
type = "jellyfin";
|
|
||||||
url = "http://127.0.0.1:8096";
|
|
||||||
key = "{{HOMEPAGE_VAR_JELLYFIN_KEY}}";
|
|
||||||
enableBlocks = true;
|
|
||||||
enableNowPlaying = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Bazarr = {
|
|
||||||
href = "https://bazarr.nordhammer.it";
|
|
||||||
description = "Subtitle management";
|
|
||||||
icon = "bazarr.png";
|
|
||||||
widget = {
|
|
||||||
type = "bazarr";
|
|
||||||
url = "http://127.0.0.1:6767";
|
|
||||||
key = "{{HOMEPAGE_VAR_BAZARR_KEY}}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Sonarr = {
|
|
||||||
href = "https://sonarr.nordhammer.it";
|
|
||||||
description = "TV show management";
|
|
||||||
icon = "sonarr.png";
|
|
||||||
widget = {
|
|
||||||
type = "sonarr";
|
|
||||||
url = "http://127.0.0.1:8989";
|
|
||||||
key = "{{HOMEPAGE_VAR_SONARR_KEY}}";
|
|
||||||
enableQueue = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Radarr = {
|
|
||||||
href = "https://radarr.nordhammer.it";
|
|
||||||
description = "Movie management";
|
|
||||||
icon = "radarr.png";
|
|
||||||
widget = {
|
|
||||||
type = "radarr";
|
|
||||||
url = "http://127.0.0.1:7878";
|
|
||||||
key = "{{HOMEPAGE_VAR_RADARR_KEY}}";
|
|
||||||
enableQueue = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Downloads = [
|
|
||||||
{
|
|
||||||
qBittorrent = {
|
|
||||||
href = "https://torrent.nordhammer.it";
|
|
||||||
description = "Torrent client";
|
|
||||||
icon = "qbittorrent.png";
|
|
||||||
widget = {
|
|
||||||
type = "qbittorrent";
|
|
||||||
url = "http://127.0.0.1:8080";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Prowlarr = {
|
|
||||||
href = "https://prowlarr.nordhammer.it";
|
|
||||||
description = "Indexer manager";
|
|
||||||
icon = "prowlarr.png";
|
|
||||||
widget = {
|
|
||||||
type = "prowlarr";
|
|
||||||
url = "http://127.0.0.1:9696";
|
|
||||||
key = "{{HOMEPAGE_VAR_PROWLARR_KEY}}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Infrastructure = [
|
|
||||||
{
|
|
||||||
Authelia = {
|
|
||||||
href = "https://auth.nordhammer.it";
|
|
||||||
description = "SSO & 2FA";
|
|
||||||
icon = "authelia.png";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
go2rtc = {
|
|
||||||
href = "https://camera.nordhammer.it";
|
|
||||||
description = "Camera streams";
|
|
||||||
icon = "go2rtc.png";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"AdGuard Home" = {
|
|
||||||
href = "https://adguard.nordhammer.it";
|
|
||||||
description = "Network DNS ad blocker";
|
|
||||||
icon = "adguard-home.png";
|
|
||||||
widget = {
|
|
||||||
type = "adguard";
|
|
||||||
url = "http://127.0.0.1:3000";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"Last Update" = {
|
|
||||||
description = "Most recent nixos-rebuild switch";
|
|
||||||
icon = "mdi-history";
|
|
||||||
widget = {
|
|
||||||
type = "customapi";
|
|
||||||
url = "http://127.0.0.1:8083/latest.json";
|
|
||||||
refreshInterval = 60000;
|
|
||||||
method = "GET";
|
|
||||||
display = "list";
|
|
||||||
mappings = [
|
|
||||||
{ field = "date"; label = "Date"; }
|
|
||||||
{ field = "changes"; label = "Changes"; }
|
|
||||||
{ field = "closure"; label = "Closure"; }
|
|
||||||
{ field = "kernel"; label = "Kernel"; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -161,7 +161,6 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
"camera.nordhammer.it" = protectedProxy 1984;
|
"camera.nordhammer.it" = protectedProxy 1984;
|
||||||
"homepage.nordhammer.it" = protectedProxy 8084;
|
|
||||||
# "7dtd.nordhammer.it" = protectedProxy 8090; # 7DTD disabled
|
# "7dtd.nordhammer.it" = protectedProxy 8090; # 7DTD disabled
|
||||||
"adguard.nordhammer.it" = protectedProxy 3000;
|
"adguard.nordhammer.it" = protectedProxy 3000;
|
||||||
# Router management UI (services/router-ui.nix). proxy_buffering off so
|
# Router management UI (services/router-ui.nix). proxy_buffering off so
|
||||||
|
|
@ -205,16 +204,6 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# --- Local-only: serves update history JSON to Homepage's customapi widget ---
|
|
||||||
"homepage-updates.local" = {
|
|
||||||
listen = [ { addr = "127.0.0.1"; port = 8083; } ];
|
|
||||||
locations."/".root = "/var/lib/homepage-updates";
|
|
||||||
extraConfig = ''
|
|
||||||
default_type application/json;
|
|
||||||
add_header Access-Control-Allow-Origin *;
|
|
||||||
'' + securityHeaders;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ let
|
||||||
"jellyfin" "sonarr" "radarr" "prowlarr" "bazarr"
|
"jellyfin" "sonarr" "radarr" "prowlarr" "bazarr"
|
||||||
"qbittorrent-nox" "sabnzbd" "authelia-main" "nginx"
|
"qbittorrent-nox" "sabnzbd" "authelia-main" "nginx"
|
||||||
"adguardhome" "crowdsec" "go2rtc"
|
"adguardhome" "crowdsec" "go2rtc"
|
||||||
"homepage-dashboard" "cloudflare-dyndns" "gitea-runner-default"
|
"cloudflare-dyndns" "gitea-runner-default"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Reads the topic at runtime (pure flake eval can't see /var/secrets).
|
# Reads the topic at runtime (pure flake eval can't see /var/secrets).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue