compsigh-minecraft/modules/backup.nix
2026-03-14 00:18:58 -07:00

61 lines
1.8 KiB
Nix

{ config, pkgs, ... }:
let
mcDataDir = "/srv/minecraft/data";
b2Bucket = "compsigh-minecraft-backups"; # TODO: change to your bucket name
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" ''
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
${pkgs.gnutar}/bin/tar czf "$TEMP_BACKUP" \
-C ${mcDataDir} world world_nether world_the_end
# 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,30";
Persistent = true;
};
};
}