103 lines
3.2 KiB
Nix
103 lines
3.2 KiB
Nix
{ 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
|
|
};
|
|
};
|
|
}
|