Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
| 00cc68b7cc |
2 changed files with 104 additions and 0 deletions
103
modules/system/homelab/mc-backup.nix
Normal file
103
modules/system/homelab/mc-backup.nix
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
{ pkgs, ... }: let
|
||||||
|
serverName = "mc0-explorers-creativity";
|
||||||
|
serviceName = "minecraft-server-${serverName}";
|
||||||
|
backupDir = "/mnt/data/backups/mc";
|
||||||
|
keepBackups = 7; # number of backups to retain
|
||||||
|
rconHost = "localhost";
|
||||||
|
rconPort = "25575";
|
||||||
|
rconPassword = "howdy";
|
||||||
|
ntfyUrl = "http://127.0.0.1:8067";
|
||||||
|
ntfyTopic = "mc-backup";
|
||||||
|
|
||||||
|
backupScript = pkgs.writeShellScriptBin "mc-backup" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
rcon() {
|
||||||
|
${pkgs.rcon-cli}/bin/rcon-cli --address "${rconHost}:${rconPort}" --password "${rconPassword}" "$@" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
BACKUP_OK=false
|
||||||
|
|
||||||
|
on_exit() {
|
||||||
|
# Always restart the server first
|
||||||
|
echo "[mc-backup] Restarting server..."
|
||||||
|
systemctl start ${serviceName}.service
|
||||||
|
|
||||||
|
# Notify via ntfy only on failure
|
||||||
|
if [ "$BACKUP_OK" != "true" ]; then
|
||||||
|
echo "[mc-backup] Sending failure notification..."
|
||||||
|
${pkgs.curl}/bin/curl -s -o /dev/null \
|
||||||
|
-H "Title: Minecraft Backup Failed" \
|
||||||
|
-H "Priority: high" \
|
||||||
|
-H "Tags: warning" \
|
||||||
|
-d "Nightly backup failed at $(date '+%Y-%m-%d %H:%M:%S'). Check logs with: journalctl -u mc-backup -n 50" \
|
||||||
|
"${ntfyUrl}/${ntfyTopic}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Always restart the server on exit, even if the script fails mid-backup
|
||||||
|
trap on_exit EXIT
|
||||||
|
|
||||||
|
# --- Countdown warnings via RCON ---
|
||||||
|
echo "[mc-backup] Sending 5-minute warning..."
|
||||||
|
rcon "say §c[Backup] §fServer will restart in §e5 minutes §ffor a scheduled backup."
|
||||||
|
|
||||||
|
sleep 240
|
||||||
|
|
||||||
|
echo "[mc-backup] Sending 1-minute warning..."
|
||||||
|
rcon "say §c[Backup] §fServer restarting in §e1 minute§f."
|
||||||
|
|
||||||
|
sleep 50
|
||||||
|
|
||||||
|
echo "[mc-backup] Sending 10-second warning..."
|
||||||
|
rcon "say §c[Backup] §fServer restarting in §e10 seconds§f."
|
||||||
|
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
rcon "say §c[Backup] §fShutting down now. Back shortly!"
|
||||||
|
|
||||||
|
# --- Save world & stop ---
|
||||||
|
echo "[mc-backup] Saving world..."
|
||||||
|
rcon "save-all"
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "[mc-backup] Stopping ${serviceName}..."
|
||||||
|
systemctl stop ${serviceName}.service
|
||||||
|
|
||||||
|
# --- Backup ---
|
||||||
|
echo "[mc-backup] Backing up to ${backupDir}..."
|
||||||
|
mkdir -p "${backupDir}"
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
||||||
|
XZ_OPT="-9e" tar -cJf "${backupDir}/mc-backup-$TIMESTAMP.tar.xz" \
|
||||||
|
-C /srv/minecraft ${serverName}
|
||||||
|
|
||||||
|
# Prune old backups, keeping the last ${toString keepBackups}
|
||||||
|
ls -t "${backupDir}"/mc-backup-*.tar.xz | tail -n +${toString (keepBackups + 1)} | xargs -r rm --
|
||||||
|
|
||||||
|
echo "[mc-backup] Backup complete: mc-backup-$TIMESTAMP.tar.xz"
|
||||||
|
BACKUP_OK=true
|
||||||
|
# Server restart is handled by the EXIT trap above
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
environment.systemPackages = [ backupScript ];
|
||||||
|
|
||||||
|
systemd.services.mc-backup = {
|
||||||
|
description = "Nightly Minecraft server backup";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${backupScript}/bin/mc-backup";
|
||||||
|
User = "root";
|
||||||
|
StandardOutput = "journal";
|
||||||
|
StandardError = "journal";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.mc-backup = {
|
||||||
|
description = "Nightly Minecraft backup timer";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily"; # fires at 00:00:00 every day
|
||||||
|
Persistent = true; # catch up if the machine was off at midnight
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ in {
|
||||||
./homelab/ai.nix
|
./homelab/ai.nix
|
||||||
./homelab/db.nix
|
./homelab/db.nix
|
||||||
./homelab/mc.nix
|
./homelab/mc.nix
|
||||||
|
./homelab/mc-backup.nix
|
||||||
|
|
||||||
./core/swapfile.nix
|
./core/swapfile.nix
|
||||||
./core/oom.nix
|
./core/oom.nix
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue