compsigh-minecraft/modules/backup.nix

67 lines
1.9 KiB
Nix

{ config, pkgs, ... }:
let
mcDataDir = "/srv/minecraft/data";
b2Bucket = "compsigh-server-backups";
in
{
systemd.services.minecraft-backup = {
description = "Backup Minecraft world to Backblaze B2";
after = [ "docker-minecraft.service" ];
path = [ pkgs.docker ];
serviceConfig = {
Type = "oneshot";
ExecStart = pkgs.writeShellScript "minecraft-backup" ''
set -euo pipefail
TEMP_BACKUP="/tmp/minecraft-world-latest.tar.gz"
# Check if the container is running
if ! docker ps --format '{{.Names}}' | grep -q '^minecraft$'; then
echo "Minecraft container not running, skipping backup"
exit 0
fi
# Flush all chunks to disk and pause saving
docker exec minecraft rcon-cli save-all flush
sleep 2
docker exec minecraft rcon-cli save-off
# Compress world data (re-enable saving even if tar fails)
if ! ${pkgs.gnutar}/bin/tar czf "$TEMP_BACKUP" \
-C ${mcDataDir} world; then
echo "tar failed, re-enabling saving"
docker exec minecraft rcon-cli save-on
exit 1
fi
# Re-enable saving immediately
docker exec minecraft rcon-cli save-on
# Upload to B2 (overwrites the single backup file)
B2_ACCOUNT=$(cat ${config.age.secrets.b2-account-id.path})
B2_KEY=$(cat ${config.age.secrets.b2-application-key.path})
${pkgs.rclone}/bin/rclone copyto \
"$TEMP_BACKUP" \
":b2:${b2Bucket}/world-latest.tar.gz" \
--b2-account "$B2_ACCOUNT" \
--b2-key "$B2_KEY" \
--no-check-dest
# Clean up local temp file
rm -f "$TEMP_BACKUP"
echo "Backup uploaded to Backblaze B2 successfully"
'';
};
};
systemd.timers.minecraft-backup = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*:00/10";
Persistent = true;
};
};
}