From 58089e558e282101bf8818f7f94ffe3123500b1e Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Tue, 9 Sep 2025 10:39:45 +0200 Subject: [PATCH] feat: auto restart foundry-vtt --- hosts/fw/modules/foundry-vtt.nix | 89 ++++++++++++++++++++++++++ hosts/fw/modules/home-assistant/pc.nix | 2 - 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/hosts/fw/modules/foundry-vtt.nix b/hosts/fw/modules/foundry-vtt.nix index 8018d8c..4f49681 100644 --- a/hosts/fw/modules/foundry-vtt.nix +++ b/hosts/fw/modules/foundry-vtt.nix @@ -3,6 +3,54 @@ let foundry-vtt = pkgs.callPackage ../pkgs/foundry-vtt {}; cids = import ../modules/staticids.nix; hostConfig = config; + url = "https://foundry-vtt.cloonar.com"; # URL to check + targetService = "container@foundry-vtt.service"; # systemd unit to restart (e.g. "docker-container@myapp.service") + threshold = 3; # consecutive failures before restart + interval = "1min"; # how often to run + timeoutSeconds = 10; # curl timeout + + checkUrlScript = pkgs.writeShellScript "check-foundry-up" '' + #!/usr/bin/env bash + set -euo pipefail + URL="$1" + TARGET="$2" + THRESHOLD="$3" + TIMEOUT="$4" + + STATE_DIR="/run/url-watchdog" + mkdir -p "$STATE_DIR" + SAFE_TARGET="$(systemd-escape --path "$TARGET")" + STATE_FILE="$STATE_DIR/$SAFE_TARGET.count" + + TMP="$(mktemp)" + # Get HTTP status; "000" if curl fails. + status="$(curl -sS -m "$TIMEOUT" -o "$TMP" -w "%{http_code}" "$URL" || echo "000")" + + fail=0 + if [[ "$status" == "502" || "$status" == "504" || "$status" == "000" ]]; then + fail=1 + fi + + count=0 + if [[ -f "$STATE_FILE" ]]; then + count="$(cat "$STATE_FILE" 2>/dev/null || echo 0)" + fi + + if [[ "$fail" -eq 1 ]]; then + count=$((count+1)) + else + count=0 + fi + + if [[ "$count" -ge "$THRESHOLD" ]]; then + printf '[%s] %s failing (%s) %sx -> restarting %s\n' "$(date -Is)" "$URL" "$status" "$count" "$TARGET" + systemctl restart "$TARGET" + count=0 + fi + + echo "$count" > "$STATE_FILE" + rm -f "$TMP" + ''; in { users.users.foundry-vtt = { isSystemUser = true; @@ -70,4 +118,45 @@ in { system.stateVersion = "24.05"; }; }; + + systemd.services."restart-foundry-vtt" = { + description = "Restart foundry-vtt container"; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.systemd}/bin/systemctl restart container@foundry-vtt.service"; + }; + }; + + systemd.timers."restart-foundry-vtt" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + # 03:00 local time (Europe/Vienna for you) + OnCalendar = "03:00"; + # If the machine was off at 03:00, run once at next boot + Persistent = true; + Unit = "restart-foundry-vtt.service"; + }; + }; + + systemd.services.foundry-vtt-watchdog = { + description = "Foundry VTT watchdog: restart ${targetService} on Nginx gateway errors"; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${checkUrlScript} ${url} ${targetService} ${toString threshold} ${toString timeoutSeconds}"; + }; + # Ensure needed tools are on PATH inside the unit + path = [ pkgs.curl pkgs.coreutils pkgs.systemd ]; + # Wait until networking is really up + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + }; + + systemd.timers.foundry-vtt-watchdog = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = interval; + OnUnitActiveSec = interval; + AccuracySec = "10s"; + }; + }; } diff --git a/hosts/fw/modules/home-assistant/pc.nix b/hosts/fw/modules/home-assistant/pc.nix index ad4be14..a939103 100644 --- a/hosts/fw/modules/home-assistant/pc.nix +++ b/hosts/fw/modules/home-assistant/pc.nix @@ -41,8 +41,6 @@ service = "wake_on_lan.send_magic_packet"; data = { mac = "04:7c:16:d5:63:5e"; - broadcast_address = "${config.networkPrefix}.96.5"; - broadcast_port = 9; }; } ];