Kopie zapasowe serwera Minecraft: jak nie stracić danych przy ataku

Kopie zapasowe serwera Minecraft: jak nie stracić danych przy ataku

Twój serwer Minecraft działa od miesięcy. Gracze budują miasta, rozwijają postacie, ekonomia się kręci. A potem przychodzi DDoS. Serwer pada w trakcie autosave. Proces Java ubity przez OOM-killera w pół ruchu. Pliki region zapisane do połowy. Level.dat wyzerowany. I oto patrzysz na pliki o rozmiarze 0 bajtów w playerdata/ i rozumiesz: kopii zapasowych nie ma.

Ta sytuacja zdarza się regularnie. Administratorzy spędzają miesiące na rozwoju serwera, ale zapominają o backupach. Albo robią je raz w tygodniu ręcznie. Albo trzymają na tym samym dysku co serwer. Wszystko to jest równoznaczne z brakiem backupów.

W tym artykule pokażę, jak skonfigurować niezawodny system kopii zapasowych dla serwera Minecraft. Bez zbędnej teorii, z konkretnymi skryptami i configami, które można skopiować i zastosować.

Dlaczego backupy są krytycznie ważne dla serwerów MC

Serwer Minecraft trzyma dane w plikach na dysku. Świat, ekwipunki, osiągnięcia, statystyki, configi pluginów, uprawnienia. To wszystko zwykłe pliki w systemie plików, i są podatne.

Główne ryzyka:

Crash podczas zapisu. Minecraft okresowo zapisuje świat na dysk. Jeśli serwer padnie w tym momencie (DDoS, OOM, kernel panic), pliki mogą znaleźć się w nieprawidłowym stanie. Plik region zapisany do połowy może spowodować utratę całego obszaru 32x32 chunków. To setki godzin pracy graczy.

Uszkodzenie level.dat. Ten plik zawiera krytyczne informacje: czas świata, pozycję spawnu, generator, reguły gry. Bez niego serwer nie wystartuje. Tak, jest level.dat_old, ale jeśli on też jest uszkodzony, masz problem.

Utrata playerdata. Pliki w world/playerdata/ trzymają ekwipunek, pozycję, zdrowie, doświadczenie każdego gracza. Jeden plik o rozmiarze 0 bajtów oznacza całkowitą utratę postępu konkretnej osoby.

Błędy administratora. Przypadkowy rm -rf, nieudana aktualizacja pluginu, testowanie na produkcji. Czynnik ludzki zabija dane nie rzadziej niż ataki.

Ataki na serwer. Ataki DDoS powodują gwałtowny spadek TPS, przeciążenie CPU i pamięci. Kiedy serwer nie wyrabia, OS może ubić proces Java. A jeśli atakujący dostał dostęp przez lukę w pluginie, może celowo uszkodzić dane.

Co konkretnie trzeba backupować

Nie wszystko na serwerze jest tak samo ważne. Oto priorytety:

Krytycznie ważne

  • world/ (i wszystkie dodatkowe światy: world_nether, world_the_end, światy pluginów)
  • world/playerdata/ - ekwipunki i postępy graczy
  • world/advancements/ - osiągnięcia
  • world/stats/ - statystyki graczy
  • plugins/ - configi i dane wszystkich pluginów
  • server.properties, spigot.yml, paper-global.yml, paper-world-defaults.yml
  • ops.json, whitelist.json, banned-players.json, banned-ips.json
  • Bazy danych MySQL/MariaDB (jeśli pluginy używają SQL)

Ważne, ale odtwarzalne

  • Pliki jar serwera i pluginów - można pobrać ponownie
  • Logi - przydatne do analizy, ale nie krytyczne dla działania
  • Cache i pliki tymczasowe - odtwarzane automatycznie

Można nie backupować

  • .cache/, libraries/ - pobierane przy starcie
  • crash-reports/ - jeśli już przeanalizowałeś crashe
  • Bardzo duże logi - zajmują miejsce w backupie bez większego pożytku

Zasada 3-2-1

Złoty standard kopii zapasowych. Prosta zasada, która działa:

  • 3 kopie danych (oryginał + 2 backupy)
  • 2 różne typy nośników (lokalny dysk + chmura, albo SSD + HDD)
  • 1 kopia w innym miejscu fizycznym (offsite)

Dla serwera Minecraft to oznacza:

  1. Oryginalne dane na serwerze
  2. Lokalny backup na osobnym dysku albo partycji
  3. Zdalny backup w chmurze (S3, Backblaze B2, Google Drive)

Dlaczego tak? Lokalny backup daje szybkość odtworzenia. Jeśli świat się uszkodzi, wrócisz go w minuty. Zdalny backup chroni przed katastrofalnymi scenariuszami: hostingowiec zgubił twoje dane, dysk fizycznie padł, serwer został skompromitowany i dane usunięto.

Backup bez zatrzymywania serwera: save-off / save-on

Główny problem: nie można po prostu kopiować plików działającego serwera Minecraft. Jeśli serwer zapisuje dane w momencie, gdy je kopiujesz, backup może zawierać niespójne dane. Chunk zapisany do połowy, playerdata otwarte do zapisu, level.dat w trakcie aktualizacji.

Rozwiązanie: komendy save-off i save-on.

#!/bin/bash
# minecraft-backup.sh - backup bez zatrzymywania serwera
# Wymaga: screen lub tmux z sesją minecraft

SERVER_DIR="/opt/minecraft"
BACKUP_DIR="/backup/minecraft"
SCREEN_NAME="minecraft"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="$BACKUP_DIR/mc-backup-$DATE.tar.gz"

# Tworzymy katalog na backupy
mkdir -p "$BACKUP_DIR"

# Informujemy graczy
screen -S "$SCREEN_NAME" -p 0 -X stuff "say Backup starting in 10 seconds...$(printf '\r')"
sleep 10

# Wyłączamy autosave
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-off$(printf '\r')"
sleep 1

# Wymuszamy zapis bieżącego stanu
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-all$(printf '\r')"
sleep 5

# Tworzymy archiwum
tar -czf "$BACKUP_FILE" \
    -C "$SERVER_DIR" \
    world/ \
    world_nether/ \
    world_the_end/ \
    plugins/ \
    server.properties \
    spigot.yml \
    paper-global.yml \
    ops.json \
    whitelist.json \
    banned-players.json \
    banned-ips.json \
    2>/dev/null

# Włączamy autosave z powrotem
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-on$(printf '\r')"

# Informujemy graczy
screen -S "$SCREEN_NAME" -p 0 -X stuff "say Backup complete!$(printf '\r')"

echo "Backup created: $BACKUP_FILE ($(du -sh "$BACKUP_FILE" | cut -f1))"

Algorytm prosty: wyłączamy autosave, robimy finalne save-all, kopiujemy pliki, włączamy autosave. Pomiędzy save-off i save-on pliki świata się nie zmieniają, i dostajemy spójny snapshot.

Ważna rzecz: nie zapomnij włączyć save-on. Jeśli skrypt wywali się z błędem po save-off, autosave zostanie wyłączony, a przy następnym crashu stracisz wszystkie zmiany od ostatniego save-all. Dodaj trap:

# Dodaj na początku skryptu po zmiennych
trap 'screen -S "$SCREEN_NAME" -p 0 -X stuff "save-on$(printf '\r')"' EXIT

Teraz save-on wykona się w każdym przypadku, nawet jeśli skrypt został przerwany.

Narzędzia: rsync, rclone, borgbackup

rsync: podstawowe narzędzie

rsync kopiuje tylko zmienione pliki. Dla codziennych backupów dużych światów to oszczędza czas i transfer.

#!/bin/bash
# rsync-backup.sh - inkrementalny backup przez rsync

SERVER_DIR="/opt/minecraft"
BACKUP_DIR="/backup/minecraft/latest"
LOG="/var/log/mc-backup.log"

# Używamy rsync do kopiowania tylko zmienionych plików
rsync -a --delete \
    --exclude='.cache/' \
    --exclude='libraries/' \
    --exclude='logs/*.gz' \
    --exclude='crash-reports/' \
    "$SERVER_DIR/" "$BACKUP_DIR/"

echo "$(date '+%Y-%m-%d %H:%M:%S') rsync backup completed" >> "$LOG"

Flaga --delete usuwa z backupu pliki, których już nie ma na serwerze. To utrzymuje backup aktualny, ale uważaj: jeśli pliki przypadkowo zostaną usunięte z serwera, --delete usunie je też z backupu. Dlatego rsync lepiej łączyć z rotacją (trzymać kilka wersji).

borgbackup: deduplikacja i szyfrowanie

borgbackup (borg) tworzy inkrementalne backupy z deduplikacją. Jeśli masz świat o rozmiarze 10 GB, ale w ciągu dnia zmieniło się tylko 200 MB chunków, borg zapisze tylko te 200 MB. Przy tym każdy backup wygląda jak pełna kopia i odtwarza się niezależnie.

# Inicjalizacja repozytorium (raz)
borg init --encryption=repokey /backup/borg-mc

# Tworzenie backupu
borg create \
    --stats \
    --compression zstd,3 \
    --exclude '*.log.gz' \
    --exclude '.cache' \
    --exclude 'libraries' \
    /backup/borg-mc::mc-{now:%Y-%m-%d_%H-%M} \
    /opt/minecraft/world \
    /opt/minecraft/plugins \
    /opt/minecraft/server.properties \
    /opt/minecraft/ops.json \
    /opt/minecraft/whitelist.json

# Automatyczna rotacja
borg prune \
    --keep-hourly=6 \
    --keep-daily=7 \
    --keep-weekly=4 \
    --keep-monthly=6 \
    /backup/borg-mc

Zalety borg dla Minecrafta:

  • Deduplikacja: te same chunki nie powielają się między backupami
  • Kompresja zstd: szybka i skuteczna dla danych binarnych
  • Szyfrowanie: backupy są zaszyfrowane, klucz trzymany lokalnie
  • Punktowe odtwarzanie: można odtworzyć jeden plik z dowolnego backupu

rclone: wysyłka do chmury

rclone działa z dziesiątkami chmur. Skonfiguruj go raz i używaj do offsite-backupów.

# Konfiguracja (interaktywnie, raz)
rclone config

# Przykładowy config dla Backblaze B2 (~/.config/rclone/rclone.conf)
# [b2-backup]
# type = b2
# account = YOUR_KEY_ID
# key = YOUR_APP_KEY

# Synchronizacja backupu do chmury
rclone sync /backup/minecraft b2-backup:mc-server-backup \
    --transfers=4 \
    --checkers=8 \
    --fast-list \
    --log-file=/var/log/rclone-backup.log \
    --log-level=NOTICE

# Dla Google Drive:
# rclone sync /backup/minecraft gdrive:mc-backup

Backblaze B2 kosztuje $0.005/GB miesięcznie. Dla średniego serwera Minecraft ze światem 5-10 GB to około $0.05 miesięcznie. Minimalne koszty dla bezpieczeństwa danych.

Automatyzacja przez cron

Backup, który trzeba odpalać ręcznie, nie będzie się odpalał. Automatyzuj wszystko.

# Otwieramy crontab
crontab -e

# Lokalny backup co 4 godziny
0 */4 * * * /opt/scripts/minecraft-backup.sh >> /var/log/mc-backup.log 2>&1

# Wysyłka do chmury raz dziennie o 4 rano
0 4 * * * /opt/scripts/cloud-upload.sh >> /var/log/mc-cloud-backup.log 2>&1

# Pełny backup borgbackup w każdą niedzielę o 5 rano
0 5 * * 0 /opt/scripts/borg-backup.sh >> /var/log/mc-borg.log 2>&1

# Czyszczenie starych backupów raz w tygodniu
0 6 * * 1 /opt/scripts/backup-cleanup.sh >> /var/log/mc-cleanup.log 2>&1

Pełny skrypt łączący wszystkie etapy:

#!/bin/bash
# full-backup-pipeline.sh
# Pełny pipeline: save-off -> backup -> borg -> rclone -> save-on

set -euo pipefail

SERVER_DIR="/opt/minecraft"
BACKUP_DIR="/backup/minecraft"
BORG_REPO="/backup/borg-mc"
SCREEN_NAME="minecraft"
RCLONE_REMOTE="b2-backup:mc-server-backup"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
LOG="/var/log/mc-backup-pipeline.log"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG"
}

# Gwarantujemy włączenie save-on przy każdym zakończeniu
trap 'screen -S "$SCREEN_NAME" -p 0 -X stuff "save-on$(printf "\r")" 2>/dev/null; log "save-on restored (trap)"' EXIT

log "=== Backup pipeline started ==="

# 1. Wyłączamy autosave
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-off$(printf '\r')"
sleep 1
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-all$(printf '\r')"
sleep 5
log "save-off + save-all done"

# 2. rsync do lokalnego katalogu
rsync -a --delete \
    --exclude='.cache/' \
    --exclude='libraries/' \
    --exclude='logs/*.gz' \
    "$SERVER_DIR/" "$BACKUP_DIR/latest/"
log "rsync completed"

# 3. Włączamy autosave (im wcześniej, tym lepiej)
screen -S "$SCREEN_NAME" -p 0 -X stuff "save-on$(printf '\r')"
log "save-on restored"

# 4. borgbackup z lokalnej kopii (serwer już działa normalnie)
borg create \
    --stats \
    --compression zstd,3 \
    "$BORG_REPO"::mc-"$DATE" \
    "$BACKUP_DIR/latest/" 2>> "$LOG"
log "borg backup created"

# 5. borg prune
borg prune \
    --keep-hourly=6 \
    --keep-daily=7 \
    --keep-weekly=4 \
    --keep-monthly=3 \
    "$BORG_REPO" 2>> "$LOG"
log "borg prune completed"

# 6. rclone do chmury (najdłuższa operacja)
rclone sync "$BACKUP_DIR/latest/" "$RCLONE_REMOTE" \
    --transfers=4 \
    --fast-list 2>> "$LOG"
log "rclone sync completed"

log "=== Backup pipeline finished ==="

Zwróć uwagę: save-on włącza się od razu po rsync, a nie na końcu skryptu. borgbackup i rclone pracują już z lokalną kopią, a serwer nie musi czekać na ich zakończenie. Okno save-off jest minimalne.

Inkrementalne vs pełne backupy

Pełny backup kopiuje wszystko za każdym razem. Prosto, niezawodnie, ale zajmuje dużo miejsca i czasu. Świat 20 GB = 20 GB na każdy backup.

Inkrementalny backup kopiuje tylko to, co się zmieniło od ostatniego razu. Szybko, oszczędnie, ale do odtworzenia potrzebny jest cały łańcuch backupów.

Optymalna strategia dla Minecrafta:

Poniedziałek: pełny backup (linia bazowa)
Wtorek-niedziela: inkrementalne backupy co 4 godziny
Następny poniedziałek: nowy pełny backup

borgbackup rozwiązuje to zadanie automatycznie. Każdy backup technicznie jest inkrementalny (trzyma tylko nowe bloki danych), ale przy odtwarzaniu wygląda jak pełny. Najlepsze z dwóch światów.

Rotacja i polityka przechowywania

Wieczne trzymanie wszystkich backupów się nie uda. Trzeba rotacji. Typowa polityka dla serwera Minecraft:

  • Ostatnie 24 godziny: backup co 4 godziny (6 kopii)
  • Ostatni tydzień: dzienny backup (7 kopii)
  • Ostatni miesiąc: tygodniowy backup (4 kopie)
  • Ostatnie 3 miesiące: miesięczny backup (3 kopie)

Razem: ~20 punktów odtworzenia pokrywających 3 miesiące historii.

Skrypt rotacji dla backupów tar:

#!/bin/bash
# backup-rotation.sh - usuwanie starych backupów

BACKUP_DIR="/backup/minecraft"

# Usuwamy backupy starsze niż 7 dni (oprócz niedzielnych)
find "$BACKUP_DIR" -name "mc-backup-*.tar.gz" -mtime +7 \
    -not -name "*_Sun_*" -delete

# Usuwamy niedzielne backupy starsze niż 30 dni
find "$BACKUP_DIR" -name "*_Sun_*.tar.gz" -mtime +30 -delete

# Pokazujemy użycie dysku
echo "Backup space usage:"
du -sh "$BACKUP_DIR"

Dla borg używaj wbudowanej komendy prune, którą już pokazaliśmy wyżej. Działa elastyczniej i pewniej niż ręczne skrypty na find.

Backup baz danych MySQL/MariaDB

Jeśli twoje pluginy używają SQL (LuckPerms, ShopGUI+, CMI, Dynmap, Plan), plikowy backup nie złapie bazy danych. Potrzebny jest osobny dump.

#!/bin/bash
# mysql-backup.sh - dump bazy danych

DB_NAME="minecraft"
DB_USER="mc_backup"
DB_PASS="secure_password_here"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y-%m-%d_%H-%M-%S)

mkdir -p "$BACKUP_DIR"

# Tworzymy dump z blokadą tabel (spójny snapshot)
mysqldump \
    --user="$DB_USER" \
    --password="$DB_PASS" \
    --single-transaction \
    --routines \
    --triggers \
    "$DB_NAME" | gzip > "$BACKUP_DIR/mc-db-$DATE.sql.gz"

echo "Database backup: $BACKUP_DIR/mc-db-$DATE.sql.gz"

# Usuwamy dumpy starsze niż 14 dni
find "$BACKUP_DIR" -name "mc-db-*.sql.gz" -mtime +14 -delete

Flaga --single-transaction jest krytycznie ważna. Tworzy spójny snapshot bazy bez blokowania tabel. Bez niej dump może zawierać dane z różnych momentów (jedna tabela się zaktualizowała, kiedy inna była jeszcze dumpowana).

Dodaj ten skrypt do pipeline'u backupu, odpalaj przed backupem plików, i włącz dump SQL do borgbackup.

Testowanie backupów: backup bez testu = brak backupu

Najczęstszy błąd: skonfigurować backupy i o nich zapomnieć. A za pół roku okazuje się, że skrypt padł trzy miesiące temu, albo backupy są, ale nie da się z nich odtworzyć.

Testuj odtwarzanie regularnie. Raz w miesiącu minimum.

#!/bin/bash
# test-restore.sh - weryfikacja odtworzenia z backupu

TEST_DIR="/tmp/mc-restore-test"
BORG_REPO="/backup/borg-mc"

# Czyścimy testowy katalog
rm -rf "$TEST_DIR"
mkdir -p "$TEST_DIR"

# Odtwarzamy ostatni backup
LATEST=$(borg list "$BORG_REPO" --last 1 --format '{archive}')
echo "Restoring: $LATEST"

borg extract "$BORG_REPO"::"$LATEST" --target "$TEST_DIR"

# Sprawdzamy krytyczne pliki
echo "=== Checking critical files ==="

# level.dat
if [ -f "$TEST_DIR/latest/world/level.dat" ]; then
    SIZE=$(stat -c%s "$TEST_DIR/latest/world/level.dat")
    if [ "$SIZE" -gt 100 ]; then
        echo "[OK] level.dat ($SIZE bytes)"
    else
        echo "[FAIL] level.dat too small ($SIZE bytes)"
    fi
else
    echo "[FAIL] level.dat missing!"
fi

# Pliki region
REGION_COUNT=$(find "$TEST_DIR/latest/world/region/" -name "*.mca" 2>/dev/null | wc -l)
EMPTY_REGIONS=$(find "$TEST_DIR/latest/world/region/" -name "*.mca" -empty 2>/dev/null | wc -l)
echo "[INFO] Region files: $REGION_COUNT total, $EMPTY_REGIONS empty"

# Player data
PLAYER_COUNT=$(find "$TEST_DIR/latest/world/playerdata/" -name "*.dat" 2>/dev/null | wc -l)
EMPTY_PLAYERS=$(find "$TEST_DIR/latest/world/playerdata/" -name "*.dat" -empty 2>/dev/null | wc -l)
echo "[INFO] Player data: $PLAYER_COUNT total, $EMPTY_PLAYERS empty"

# Configi pluginów
PLUGIN_COUNT=$(find "$TEST_DIR/latest/plugins/" -maxdepth 1 -type d 2>/dev/null | wc -l)
echo "[INFO] Plugin directories: $PLUGIN_COUNT"

# Sprawdzamy server.properties
if [ -f "$TEST_DIR/latest/server.properties" ]; then
    echo "[OK] server.properties present"
else
    echo "[FAIL] server.properties missing!"
fi

# Sprawdzamy ops.json
if [ -f "$TEST_DIR/latest/ops.json" ]; then
    echo "[OK] ops.json present"
else
    echo "[WARN] ops.json missing"
fi

# Czyszczenie
rm -rf "$TEST_DIR"
echo "=== Restore test complete ==="

Odpalaj ten skrypt automatycznie raz w tygodniu i wysyłaj wynik do siebie na Discord/Telegram. Jeśli test się nie powiedzie, dowiesz się o tym, zanim backup naprawdę będzie potrzebny.

Szybkie odtworzenie po ataku

Atak DDoS uszkodził dane. Gracze czekają. Każda minuta przestoju kosztuje ci audytorium. Oto krok po kroku plan szybkiego odtworzenia:

# 1. Zatrzymujemy serwer (jeśli jeszcze działa)
screen -S minecraft -p 0 -X stuff "stop$(printf '\r')"
sleep 10

# 2. Przenosimy uszkodzone dane (nie usuwamy!)
mv /opt/minecraft/world /opt/minecraft/world_corrupted_$(date +%Y%m%d)

# 3. Odtwarzamy z ostatniego backupu

# Wariant A: z kopii rsync (najszybszy)
cp -a /backup/minecraft/latest/world /opt/minecraft/world

# Wariant B: z borg
borg extract /backup/borg-mc::ARCHIVE_NAME \
    --target /opt/minecraft \
    latest/world

# Wariant C: z archiwum tar
tar -xzf /backup/minecraft/mc-backup-LATEST.tar.gz \
    -C /opt/minecraft world/

# 4. Odtwarzamy bazę danych (jeśli trzeba)
gunzip < /backup/mysql/mc-db-LATEST.sql.gz | mysql minecraft

# 5. Sprawdzamy uprawnienia
chown -R minecraft:minecraft /opt/minecraft/world

# 6. Uruchamiamy serwer
screen -S minecraft -X stuff "/opt/minecraft/start.sh$(printf '\r')"

Z kopii rsync odtworzenie zajmuje minuty. Z borg z deduplikacją trochę dłużej, ale nadal szybko. Z backupu w chmurze może być potrzebny czas na pobranie, dlatego lokalna kopia jest krytycznie ważna.

Rada: zachowaj uszkodzone dane. Nie usuwaj ich od razu. Może później będziesz chciał wyciągnąć z nich coś, co nie trafiło do backupu (na przykład dane utworzone po ostatnim backupie).

Bezpieczeństwo backupów

Backup zawiera wszystko: configi z hasłami do bazy, hasła RCON, tokeny API pluginów. Jeśli ktoś dostanie dostęp do backupu, dostanie pełną kontrolę nad serwerem.

Szyfrowanie

borgbackup wspiera szyfrowanie od razu. Przy inicjalizacji repozytorium z --encryption=repokey wszystkie dane są szyfrowane AES-256.

Dla archiwów tar użyj gpg:

# Szyfrowanie backupu
tar -czf - /opt/minecraft/world /opt/minecraft/plugins | \
    gpg --symmetric --cipher-algo AES256 \
    --output /backup/mc-encrypted-$(date +%Y%m%d).tar.gz.gpg

# Deszyfrowanie
gpg --decrypt /backup/mc-encrypted-20260403.tar.gz.gpg | \
    tar -xzf - -C /opt/minecraft

Kontrola dostępu

# Ograniczamy dostęp do katalogu backupów
chmod 700 /backup/minecraft
chown root:root /backup/minecraft

# Dla configu rclone (zawiera klucze do chmur)
chmod 600 ~/.config/rclone/rclone.conf

Osobny użytkownik do backupów

Stwórz osobnego użytkownika z minimalnymi uprawnieniami:

# Tworzymy użytkownika do backupów
useradd -r -s /bin/bash -d /backup mc-backup

# Dajemy read-only dostęp do danych serwera
setfacl -R -m u:mc-backup:rx /opt/minecraft
setfacl -R -d -m u:mc-backup:rx /opt/minecraft

# Dajemy pełny dostęp do katalogu backupów
chown -R mc-backup:mc-backup /backup/minecraft

Jeśli serwer zostanie skompromitowany, atakujący z uprawnieniami użytkownika minecraft nie będzie mógł usunąć backupów, bo należą do innego użytkownika.

Pluginy do backupów

Jeśli nie chcesz bawić się w skrypty bash, są pluginy, które robią backupy z poziomu Minecrafta.

DriveBackupV2

Automatycznie backupuje do Google Drive, OneDrive albo FTP. Konfiguracja przez config:

# plugins/DriveBackupV2/config.yml
backup-schedule:
  cron: "0 */6 * * *"  # Co 6 godzin
backup-list:
  - path: "world"
    format: "zip"
  - path: "plugins"
    format: "zip"
google-drive:
  enabled: true
keep-count: 10

eBackup

Lekki plugin do lokalnych backupów ze wsparciem FTP/SFTP:

# plugins/eBackup/config.yml
backup:
  interval: 240  # minuty
  format: tar.gz
  worlds: true
  plugins: true
  max-backups: 20

Pluginy są wygodne dla małych serwerów. Ale dla poważnej infrastruktury lepiej używać narzędzi systemowych (borg + rclone + cron). Działają na poziomie OS, nie zależą od stanu procesu Java, i dają pełną kontrolę nad procesem.

Offsite-storage: gdzie wysyłać backupy

Amazon S3 / kompatybilne z S3

# rclone.conf dla Wasabi (kompatybilne z S3, taniej niż AWS)
# [wasabi]
# type = s3
# provider = Wasabi
# access_key_id = YOUR_KEY
# secret_access_key = YOUR_SECRET
# endpoint = s3.eu-central-1.wasabisys.com

rclone sync /backup/minecraft wasabi:mc-backup-bucket

Backblaze B2

Najbardziej budżetowa opcja. $0.005/GB przechowywania, $0.01/GB pobierania, pierwsze 10 GB za darmo.

rclone sync /backup/minecraft b2-backup:mc-server-backup \
    --fast-list \
    --transfers=4

Google Drive (przez rclone)

15 GB za darmo. Dla małego serwera wystarczy.

rclone sync /backup/minecraft gdrive:mc-backup \
    --drive-chunk-size=64M

Rekomendacja: zacznij od Backblaze B2. Minimalny koszt, wysoka niezawodność, dobra prędkość. Dla większości serwerów Minecraft miesięczny rachunek będzie niższy niż $1.

Monitoring backupów

Backupy są bezużyteczne, jeśli po cichu się psują. Dodaj monitoring:

#!/bin/bash
# check-backup-health.sh

BACKUP_DIR="/backup/minecraft/latest"
MAX_AGE_HOURS=6
DISCORD_WEBHOOK="https://discord.com/api/webhooks/YOUR_WEBHOOK"

# Sprawdzamy wiek ostatniego backupu
LATEST_MOD=$(stat -c %Y "$BACKUP_DIR/world/level.dat" 2>/dev/null || echo 0)
NOW=$(date +%s)
AGE_HOURS=$(( (NOW - LATEST_MOD) / 3600 ))

if [ "$AGE_HOURS" -gt "$MAX_AGE_HOURS" ]; then
    curl -s -H "Content-Type: application/json" \
        -d "{\"content\":\"[ALERT] MC backup is $AGE_HOURS hours old (max: $MAX_AGE_HOURS). Check backup system!\"}" \
        "$DISCORD_WEBHOOK"
fi

# Sprawdzamy rozmiar backupu (zbyt mały = coś nie tak)
WORLD_SIZE=$(du -sm "$BACKUP_DIR/world/" 2>/dev/null | cut -f1)
if [ "${WORLD_SIZE:-0}" -lt 100 ]; then
    curl -s -H "Content-Type: application/json" \
        -d "{\"content\":\"[ALERT] MC world backup is only ${WORLD_SIZE}MB. Expected >100MB. Possible backup failure!\"}" \
        "$DISCORD_WEBHOOK"
fi

Dodaj do cron: 0 */2 * * * /opt/scripts/check-backup-health.sh. Jeśli backup nie aktualizował się dłużej niż 6 godzin albo świat jest podejrzanie mały, dostaniesz powiadomienie na Discordzie.

DDoS a backupy: jak chronić dane przy ataku

Atak DDoS tworzy idealne warunki do utraty danych. Serwer przeciążony, TPS spada do zera, OOM-killer może ubić Javę w każdej chwili. Jeśli w tym momencie szło autosave, dane się uszkodzą.

Co robić:

  1. Skonfiguruj ochronę przed DDoS. Serwisy takie jak MineGuard filtrują ataki, zanim trafią na serwer. Brak przeciążenia, brak crashy, brak uszkodzeń.

  2. Zwiększ częstotliwość backupów przy zagrożeniu. Jeśli twój serwer jest regularnie atakowany, ustaw backupy co 2 godziny zamiast 4. Maksymalna utrata danych (RPO) skróci się dwukrotnie.

  3. Nie polegaj tylko na autosave. Autosave w Minecrafcie nie zastępuje backupów. Autosave nadpisuje te same pliki. Jeśli się uszkodzą, autosave zapisze uszkodzoną wersję na wierzchu normalnej.

  4. Trzymaj lokalny backup na osobnym dysku. Jeśli główny dysk zacznie umierać z powodu obciążenia (tak, to się zdarza przy długich atakach), backup na tym samym dysku umrze razem z nim.

Więcej o odtwarzaniu po atakach przeczytaj w naszym artykule o odtwarzaniu po DDoS. A o podstawowej ochronie serwera opowie checklist bezpieczeństwa na 2026 rok.

Checklist: konfiguracja backupów w 30 minut

Jeśli doczytałeś do tego miejsca i nadal nie masz backupów, oto plan na 30 minut:

  1. [5 min] Stwórz katalog /backup/minecraft i skrypt minecraft-backup.sh z tego artykułu
  2. [3 min] Dodaj skrypt do cron (co 4 godziny)
  3. [5 min] Zainstaluj borgbackup (apt install borgbackup) i zainicjalizuj repozytorium
  4. [5 min] Zainstaluj rclone (apt install rclone) i skonfiguruj Backblaze B2 (za darmo do 10 GB)
  5. [5 min] Skonfiguruj skrypt wysyłki do chmury i dodaj do cron
  6. [5 min] Odpal pierwszy backup ręcznie i upewnij się, że wszystko działa
  7. [2 min] Skonfiguruj monitoring (Discord webhook przy błędzie)

30 minut teraz uratuje tygodnie pracy potem. Serwer można postawić od nowa. Świata zbudowanego przez graczy w pół roku nie da się odtworzyć.


Chroń swój serwer przed atakami DDoS

Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.

Wypróbuj za darmo


Powiązane artykuły