Как настроить автоматические резервные копии

1. Подготовка окружения и структура каталогов

Перед настройкой автоматизации определимся с расположением файлов сервера и хранилищем бэкапов. На выделенном сервере proxify.cloud (Ubuntu 22.04/24.04) стандартная практика — выносить игровые данные в /opt/minecraft, а бэкапы — в отдельный раздел или директорию /var/backups/minecraft.

  1. Подключитесь к серверу по SSH (данные для входа указаны в панели proxify.cloud во вкладке «Консоль» или «Сеть»):
    ssh root@<IP-адрес_сервера>
    
  2. Создайте структуру каталогов:
    mkdir -p /opt/minecraft/server
    mkdir -p /var/backups/minecraft/daily
    mkdir -p /var/backups/minecraft/weekly
    mkdir -p /var/backups/minecraft/monthly
    
  3. Назначьте владельца пользователю, под которым запускается сервер (обычно minecraft или ubuntu):
    useradd -r -s /bin/false minecraft 2>/dev/null || true
    chown -R minecraft:minecraft /opt/minecraft
    chown -R minecraft:minecraft /var/backups/minecraft
    

2. Скрипт резервного копирования с ротацией

Создадим универсальный скрипт, который архивирует папку сервера, исключает кэш/логи, и реализует схему GFS (Grandfather-Father-Son): ежедневные храним 7 дней, еженедельные — 4 недели, ежемесячные — 6 месяцев.

  1. Создайте файл скрипта:
    nano /usr/local/bin/mc-backup.sh
    
  2. Вставьте следующий код (замените SERVER_DIR при необходимости):
    #!/bin/bash
    # Автоматическое резервное копирование Minecraft сервера
    # Настройка для хостинга proxify.cloud (Ubuntu + Proxmox)
    
    set -euo pipefail
    
    # === КОНФИГУРАЦИЯ ===
    SERVER_DIR="/opt/minecraft/server"
    BACKUP_BASE="/var/backups/minecraft"
    DATE=$(date +"%Y-%m-%d_%H-%M-%S")
    HOSTNAME=$(hostname -s)
    ARCHIVE_NAME="${HOSTNAME}_mc_${DATE}.tar.gz"
    LOG_FILE="/var/log/mc-backup.log"
    RETENTION_DAILY=7
    RETENTION_WEEKLY=4
    RETENTION_MONTHLY=6
    # =====================
    
    exec >> "$LOG_FILE" 2>&1
    echo "[$(date)] === Начало бэкапа ==="
    
    # Определяем тип бэкапа по дне недели и числу месяца
    DAY_OF_WEEK=$(date +%u)  # 1=Пн ... 7=Вс
    DAY_OF_MONTH=$(date +%d)
    
    if [[ "$DAY_OF_MONTH" == "01" ]]; then
        TYPE="monthly"
        DEST_DIR="${BACKUP_BASE}/monthly"
        RETENTION=$RETENTION_MONTHLY
    elif [[ "$DAY_OF_WEEK" == "7" ]]; then
        TYPE="weekly"
        DEST_DIR="${BACKUP_BASE}/weekly"
        RETENTION=$RETENTION_WEEKLY
    else
        TYPE="daily"
        DEST_DIR="${BACKUP_BASE}/daily"
        RETENTION=$RETENTION_DAILY
    fi
    
    FULL_PATH="${DEST_DIR}/${ARCHIVE_NAME}"
    
    # Исключаем мусор: кэш, логи, временные файлы плагинов
    EXCLUDES=(
        "--exclude=*/logs/*"
        "--exclude=*/crash-reports/*"
        "--exclude=*/dynmap/web/tiles/*"
        "--exclude=*/plugins/dynmap/*"
        "--exclude=*/cache/*"
        "--exclude=*.tmp"
        "--exclude=*.jar.tmp"
    )
    
    echo "[$(date)] Тип: $TYPE | Куда: $FULL_PATH"
    
    # Создаем архив с сохранением прав и симлинков
    tar -czf "$FULL_PATH" "${EXCLUDES[@]}" -C "$(dirname "$SERVER_DIR")" "$(basename "$SERVER_DIR")"
    
    # Проверка целостности
    if tar -tzf "$FULL_PATH" >/dev/null; then
        SIZE=$(du -h "$FULL_PATH" | cut -f1)
        echo "[$(date)] Успешно. Размер: $SIZE"
    else
        echo "[$(date)] ОШИБКА: Архив поврежден!" >&2
        rm -f "$FULL_PATH"
        exit 1
    fi
    
    # Ротация: удаляем старые файлы выбранного типа
    find "$DEST_DIR" -type f -name "${HOSTNAME}_mc_*.tar.gz" -mtime +$RETENTION -delete
    echo "[$(date)] Ротация $TYPE завершена (хранится $RETENTION дней)"
    
    echo "[$(date)] === Бэкап завершен ==="
    
  3. Сделайте скрипт исполняемым:
    chmod +x /usr/local/bin/mc-backup.sh
    

3. Настройка systemd-таймера (рекомендуемый способ)

Вместо cron используем systemd — он логирует вывод, управляет параллелизмом и работает надежнее на выделенных серверах proxify.cloud.

  1. Создайте unit-сервис:
    nano /etc/systemd/system/mc-backup.service
    
    Содержимое:
    [Unit]
    Description=Minecraft Server Backup
    Documentation=man:mc-backup.sh(1)
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/mc-backup.sh
    User=minecraft
    Group=minecraft
    # Ограничение ресурсов, чтобы не затормозить игровой процесс
    Nice=10
    IOSchedulingClass=best-effort
    IOSchedulingPriority=7
    MemoryMax=512M
    CPUQuota=50%
    
  2. Создайте таймер (запуск каждый день в 04:30, когда онлайн минимален):
    nano /etc/systemd/system/mc-backup.timer
    
    Содержимое:
    [Unit]
    Description=Daily Minecraft Backup Timer
    
    [Timer] 04:30:00
    Persistent=true
    RandomizedDelaySec=15m
    AccuracySec=1m
    
    [Install]
    WantedBy=timers.target
    
  3. Активируйте и запустите:
    systemctl daemon-reload
    systemctl enable --now mc-backup.timer
    
  4. Проверьте статус:
    systemctl list-timers --all | grep mc-backup
    journalctl -u mc-backup.service -f
    

4. Инкрементальные бэкапы через rsync (для частых снапшотов)

Полный tar раз в сутки — база. Для RPO < 24h добавьте rsync-зеркало, обновляемое каждые 30 минут. Это не заменяет полные бэкапы, но позволяет откатиться к состоянию «полчаса назад» за секунды.

  1. Скрипт /usr/local/bin/mc-sync.sh:
    #!/bin/bash
    set -euo pipefail
    SRC="/opt/minecraft/server/"
    DST="/var/backups/minecraft/sync_latest/"
    mkdir -p "$DST"
    # --delete удаляет в назначении то, чего нет в источнике (осторожно!)
    # --link-dest создает жесткие ссылки на неизмененные файлы (экономия места)
    PREV="/var/backups/minecraft/sync_hourly/$(date -d '30 minutes ago' +%Y-%m-%d_%H-%M)"
    rsync -aH --delete --exclude='logs/' --exclude='crash-reports/' --exclude='dynmap/web/tiles/' \
        ${PREV:+--link-dest="$PREV"} "$SRC" "$DST"
    # Ротация hourly-слоев (храним 48 слоев = сутки)
    HOURLY_DIR="/var/backups/minecraft/sync_hourly/$(date +%Y-%m-%d_%H-%M)"
    cp -al "$DST" "$HOURLY_DIR"
    find /var/backups/minecraft/sync_hourly -mindepth 1 -maxdepth 1 -type d -mmin +2880 -exec rm -rf {} \;
    
  2. Таймер каждые 30 минут (/etc/systemd/system/mc-sync.timer):
    [Timer]
    Persistent=true
    
    Сервис mc-sync.service аналогичен mc-backup.service, но ExecStart=/usr/local/bin/mc-sync.sh.

5. Отправка бэкапов в удаленное хранилище (S3 / FTP / SFTP)

Хранение бэкапов только на локальном диске выделенного сервера proxify.cloud — риск (сбой RAID, ошибка админа, ransomware). Настройте выгрузку в S3-совместимое хранилище (Selectel, Yandex Cloud, AWS, MinIO).

Вариант А: rclone (универсально)

  1. Установите rclone:
    curl https://rclone.org/install.sh | bash
    
  2. Настройте.remote (интерактивно):
    rclone config
    # n -> name: s3_backup -> type: s3 -> provider: Other -> env_auth: false
    # access_key_id, secret_access_key, region, endpoint, location_constraint, acl: private
    
  3. Добавьте в mc-backup.sh после успешного создания архива:
    # Выгрузка только daily/weekly/monthly (sync_latest не нужен)
    rclone copy "$FULL_PATH" "s3_backup:minecraft-backups/$(basename "$DEST_DIR")/" \
        --log-level INFO --stats 30s --bwlimit 10M
    
    --bwlimit 10M ограничит канал, не мешая игрокам.

Вариант Б: AWS CLI (если используете чистый S3)

apt update && apt install -y awscli
aws configure set default.region eu-central-1
aws configure set default.s3.max_concurrent_requests 10
# В скрипте:
aws s3 cp "$FULL_PATH" "s3://my-bucket/minecraft/$(basename "$DEST_DIR")/" --storage-class STANDARD_IA

6. Бэкап системных конфигураций (Proxmox / Ubuntu)

Minecraft-сервер — не только файлы мира. Нужен бэкап:

  • /etc/systemd/system/mc-*.service / mc-*.timer
  • /etc/nginx/sites-available/ (если есть прокси)
  • /etc/fail2ban/jail.local
  • /root/.ssh/authorized_keys
  • Список пакетов: dpkg --get-selections > /var/backups/minecraft/dpkg-list.txt

Добавьте в mc-backup.sh перед tar:

CONF_ARCHIVE="${DEST_DIR}/${HOSTNAME}_config_${DATE}.tar.gz"
tar -czf