RE:NODE

Бэкапы сервера на свой ПК: агент резервного копирования для Windows

Автор Команда RE:NODE
16 мин чтения


Бэкап, который хранится у того же провайдера, что и защищаемый им сервер, спасает от большинства случайностей, но не от всех. Не спасает он там, где вы теряете доступ к стороне провайдера: сервер удалён, платёж просрочен, аккаунт взломан. Решение дешёвое: держать вторую копию на машине, которую контролируете вы, обычно на том самом ПК, за которым вы это читаете. Можно делать это вручную из вкладки Backups в панели, а можно поручить небольшому скрипту по расписанию: получить список готовых бэкапов сервера, скачать те, которых ещё нет, проверить, что каждый архив открывается, и удалить самые старые локальные копии. В этой статье мы собираем такой скрипт для Windows, ставим его в Task Scheduler и разбираем то, в чём чаще всего ошибаются: что архив содержит и чего не содержит, где хранить API-ключ и как отличить хорошую копию от повреждённой.

Одна оговорка перед началом, потому что название её провоцирует. У нас есть собственная программа, тоже называется RENODE Backup Agent: она каждый день забирает копии с ноды для нашей платформы. Она внутренняя, скачать её нельзя. Ниже описана та же идея, но собранная из того, что уже есть на любой машине с Windows, и направленная на ваши серверы.

Зачем нужна копия на вашей машине#

Бэкапы в хостинг-панели уже гораздо лучше, чем ничего. В RE:NODE они хранятся вне машины, которую защищают, поэтому умерший диск на ноде не уносит их с собой, а любой бэкап можно заблокировать, чтобы ротация его не удалила. Это закрывает типичные сбои: неудачное обновление плагина, повреждённый мир, правка конфига, после которой сервер не запускается.

Чего бэкап на стороне провайдера закрыть не может, так это саму сторону провайдера. Простые случаи:

  • Сервер удалён. Удаление сервера в RE:NODE удаляет и его бэкапы, в том числе заблокированные. Для приватности это правильное поведение, а значит, ошибочное удаление или субпользователь со слишком широкими правами уничтожает все копии разом.
  • Услуга истекла. Карта просрочена, письмо о продлении ушло в спам, а сервер, за которым вы перестали следить, прошёл льготный период. Что бы потом ни случилось с файлами, забрать их вы уже не сможете.
  • Аккаунт взломан. Тот, у кого есть пароль от вашей панели и нет 2FA, первым делом может удалить бэкапы. Копия на вашем ПК для него недосягаема.
  • Вы хотите уйти. Переезд к другому хостеру или на домашнюю машину начинается с наличия данных. Папка с архивами на вашем диске - самая лёгкая миграция в вашей жизни.

Это старое правило 3-2-1 с подставленными числами: три копии (живой сервер, бэкап в панели, ваш ПК) на двух видах носителей, одна из них - в стороне от двух других. Ваш ПК и есть эта копия «в стороне». Она не идеальна - домашние диски выходят из строя, ноутбуки крадут - но ломается она по совсем другим причинам, чем хостинговая сторона, и в этом весь смысл. О стратегии в целом читайте в статье game server backup strategy: там разобраны слоты, частота и что блокировать.

Что RE:NODE уже делает, а что оставляет вам#

Прежде чем добавлять ещё одну копию, полезно знать, какие уже есть, - тогда понятно, зачем нужна новая.

  • Ваши бэкапы. В каждом тарифе есть слоты для бэкапов: на большинстве игровых тарифов их два, на тарифах для приложений, сайтов и баз данных - больше. Вы создаёте их вручную или по расписанию, восстанавливаете одной кнопкой, скачиваете и блокируете те, что хотите сохранить. Они хранятся вне машины, которую защищают. Именно их мы и будем скачивать.
  • Ночные системные бэкапы. Каждый сервер также копируется каждую ночь, независимо от числа слотов в тарифе и вне вашей квоты. Эти копии наши: они не отображаются во вкладке Backups, и скачать их нельзя. Если нужно что-то восстановить из такой копии, это делается через поддержку. Как они работают, объясняет статья Nightly backups outside your quota.
  • Бэкапы платформы. Отдельно сама платформа каждую ночь копируется на отдельное оборудование, копии проверяются и прореживаются, а мы каждый день забираем копии с ноды.

Ни одна из этих трёх копий не находится у вас в руках. Ночной системный бэкап - страховка, которую мы держим на случай инцидентов; он не заменяет ваш собственный, и достать его в три часа ночи, когда он нужен, вы не сможете. Копия на вашем ПК - единственная, которая не зависит ни от кого, кроме вас.

расписание или кнопказагрузка по HTTPSкопия раз в неделюЖивой серверфайлы на нодеБэкапы в панеливаши слоты, вне нодыВаш ПКскачивание по расписаниюВнешний дискпо желанию, офлайн
Три копии, и одна у вас в руках

Что содержит архив бэкапа#

Прежде чем что-то автоматизировать, чётко поймите, что именно вы забираете: самая частая неожиданность при восстановлении - то, чего в архиве никогда не было.

ЧтоЕсть в архиве бэкапа?Как сохранить копию
Файлы сервера (мир, конфиги, плагины)ДаСкачать архив
Слот базы данных (MySQL)НетСделать дамп отдельно
Файлы из списка .pteroignoreНетУбрать строку или скопировать по SFTP
Переменные запускаНетЗаписать или сделать скриншот вкладки Startup

Бэкап сервера - это .tar.gz с файлами сервера. База данных, созданная во вкладке Databases панели, живёт на сервере баз данных, а не в файловой системе сервера, поэтому в архив она не попадает. Если ваши плагины Minecraft, ресурсы FiveM или Discord-бот хранят данные в такой базе, одного файлового бэкапа хватит лишь на то, чтобы получить сервер, который не может найти свои данные. Делайте дамп базы отдельно - команды есть в статье mysqldump backup and restore - и кладите дамп в файлы сервера до запуска бэкапа, тогда он попадёт в архив.

Вторая дыра - .pteroignore. Это файл в корне сервера, работающий как .gitignore: всё, что в нём перечислено, при создании бэкапа пропускается. Он удобен, чтобы не копировать логи и кэши, и опасен, если кто-то несколько месяцев назад добавил туда world/, чтобы сэкономить место. Откройте его, прежде чем доверять любому архиву.

Переменные запуска - версия, jar-файл, значения окружения на вкладке Startup - тоже не файлы. Запишите их один раз. Восстанавливать их по памяти во время аварии долго.

Вручную: скачивание из вкладки Backups#

Если копия нужна только время от времени, ничего устанавливать не придётся.

  1. Откройте сервер в панели и перейдите на вкладку Backups.
  2. Если последний бэкап старый, нажмите кнопку создания нового и дождитесь, пока он получит статус завершённого.
  3. Откройте меню этого бэкапа и выберите Download. Браузер скачает .tar.gz по короткоживущей подписанной ссылке.
  4. Переложите файл туда, где это не папка загрузок, и переименуйте, добавив дату и название сервера.

Для разового случая - перед рискованным изменением или перед отменой сервера - этого достаточно. Но рутиной резервного копирования это не является: всё держится на том, что вы не забудете, а нужнее всего бывают бэкапы за ту неделю, когда вы забыли. Остальная часть статьи делает процесс автоматическим. О бэкапах на стороне панели рассказано также в руководстве по бэкапам.

Автоматизация через PowerShell и клиентский API#

Панель RE:NODE построена на Pterodactyl, и её клиентский API - то, чем пользуются страницы самой панели, чтобы показать список бэкапов и скачать их. С клиентским API-ключом те же два запроса можно отправлять из скрипта. Собственной документации по API мы не публикуем, поэтому считайте всё ниже описанием клиентского API upstream-проекта Pterodactyl и проверяйте на своём сервере, прежде чем на него полагаться.

Вам понадобятся три вещи:

  • API-ключ. Создайте его в панели в разделе API credentials вашего аккаунта. Он начинается с ptlc_. Ключ можно ограничить определёнными адресами; если у вашего домашнего подключения постоянный IP, сделайте это. Если IP меняется, ограниченный ключ перестанет работать - это безопаснее открытого ключа, но об этом стоит помнить.
  • Короткий ID сервера. Это восьмисимвольная часть адреса сервера в панели, например a1b2c3d4 в /server/a1b2c3d4.
  • Папка с запасом места. Умножьте размер архива на число копий, которые хотите хранить, и добавьте запас.

Храните ключ в пользовательской переменной окружения, а не в скрипте, чтобы скриптом можно было делиться или коммитить его, не раскрывая ключ:

code
setx RENODE_API_KEY "ptlc_your_key_here"

setx записывает переменную для будущих сессий, поэтому после неё откройте новое окно PowerShell. Запланированная задача, которую мы создадим ниже, запускается от вашего пользователя и эту переменную видит.

Теперь сам скрипт. Сохраните его как C:\ServerBackups\pull.ps1:

pull.ps1
$Panel  = 'https://panel.renode.space'$Server = 'a1b2c3d4'$Dest   = "C:\ServerBackups\$Server"$Keep   = 14$Key    = $env:RENODE_API_KEY[Net.ServicePointManager]::SecurityProtocol = 'Tls12'$ProgressPreference = 'SilentlyContinue'$Headers = @{ Authorization = "Bearer $Key"; Accept = 'application/json' }$Base = "$Panel/api/client/servers/$Server/backups"New-Item -ItemType Directory -Force -Path $Dest | Out-Null$Log = Join-Path $Dest 'pull.log'$list = Invoke-RestMethod -Headers $Headers -Uri $Baseforeach ($b in $list.data) {  $a = $b.attributes  if (-not $a.is_successful -or -not $a.completed_at) { continue }  $stamp = ([datetime]$a.completed_at).ToString('yyyy-MM-dd_HHmm')  $file  = Join-Path $Dest ("$stamp-" + $a.uuid.Substring(0,8) + '.tar.gz')  if (Test-Path $file) { continue }  $link = Invoke-RestMethod -Headers $Headers -Uri "$Base/$($a.uuid)/download"  Invoke-WebRequest -Uri $link.attributes.url -OutFile "$file.part" -UseBasicParsing  tar -tzf "$file.part" > $null 2>&1  if ($LASTEXITCODE -ne 0) {    Add-Content $Log "$(Get-Date -f s) BAD archive $stamp, kept as .part"    continue  }  Move-Item "$file.part" $file  Add-Content $Log "$(Get-Date -f s) pulled $stamp $($a.name)"}Get-ChildItem $Dest -Filter *.tar.gz |  Sort-Object LastWriteTime -Descending |  Select-Object -Skip $Keep |  Remove-Item

Скрипт написан для Windows PowerShell 5.1 - эта версия есть на любой машине с Windows 10 и 11, так что ничего устанавливать не нужно. Блок помечен как обычный текст только из-за того, как блог подсвечивает код; сам файл - обычный .ps1.

Что делает каждая часть

Первый блок - настройки. $Keep - сколько архивов хранить на ПК; четырнадцать при ежедневном бэкапе в панели - это две недели. Строка с SecurityProtocol принудительно включает TLS 1.2, который на старых установках 5.1 по умолчанию подхватывается не всегда. $ProgressPreference важнее, чем кажется: в Windows PowerShell 5.1 Invoke-WebRequest перерисовывает индикатор прогресса на каждом блоке данных, и на многогигабайтном архиве одно это может замедлить загрузку в несколько раз.

Цикл запрашивает у панели бэкапы сервера и пропускает те, что завершились ошибкой или ещё выполняются. Каждому готовому бэкапу присваивается имя файла из времени завершения и первых восьми символов его UUID, так что имена сортируются по дате и не пересекаются. Если файл уже существует, скрипт идёт дальше - поэтому его безопасно запускать сколько угодно часто. Он скачивает только то, чего у него нет.

Для нового бэкапа он запрашивает ссылку для скачивания - это подписанный URL, срок действия которого вскоре истекает, - и загружает файл в .part. Только после того, как tar -tzf прочитал весь архив без ошибок, файл переименовывается в .tar.gz. Этот один шаг отличает папку с бэкапами от папки с файлами, которые лишь выглядят как бэкапы. tar входит в состав Windows 10 и 11, так что и здесь ничего дополнительного не нужно.

Последний конвейер - это хранение: отсортировать архивы от новых к старым, пропустить те, что нужно оставить, остальные удалить. Он затрагивает только файлы .tar.gz в папке этого сервера, поэтому испорченный .part остаётся на месте, чтобы вы могли на него посмотреть, а ничто другое на диске в зону действия не попадает.

Несколько серверов

Сделайте $Server списком и оберните тело скрипта во второй цикл или держите по одной копии скрипта на сервер с отдельной папкой. Отдельные папки проще понимать при восстановлении, а сервер с неработающим ключом не останавливает остальные.

Запуск по расписанию через Task Scheduler#

Скрипт, о запуске которого нужно помнить, - это тот же ручной способ, только с лишними шагами. Запускать его за вас будет планировщик задач Windows. Откройте PowerShell от обычного пользователя и зарегистрируйте задачу:

Register the task (PowerShell)
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `  -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\ServerBackups\pull.ps1'$daily  = New-ScheduledTaskTrigger -Daily -At 9am$logon  = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME$opts   = New-ScheduledTaskSettingsSet -StartWhenAvailable `  -ExecutionTimeLimit (New-TimeSpan -Hours 3)Register-ScheduledTask -TaskName 'Server backup pull' `  -Action $action -Trigger $daily,$logon -Settings $opts

Триггера два - намеренно. Домашний ПК часто выключен в то время, которое вы выберете, поэтому одного ежедневного триггера мало, и дни будут пропадать. Триггер при входе запускает скрипт всякий раз, когда вы входите в систему, а -StartWhenAvailable говорит Windows выполнить пропущенный ежедневный запуск, как только машина снова включится. Поскольку скрипт скачивает только то, чего у него нет, второй запуск за утро обойдётся в один запрос к API.

-ExecutionTimeLimit не даёт зависшей загрузке висеть вечно; три часа для большинства архивов с запасом. Если у вас серверы на десятки гигабайт и медленный канал, увеличьте этот лимит.

Согласуйте с расписанием бэкапов в панели

Скачать можно только то, что уже существует. В панели откройте вкладку Schedules сервера и добавьте расписание с задачей бэкапа, указав cron-выражение на нужное время. Если бэкап в панели запускается в 05:00, а ваш ПК забирает копии в 09:00 и при входе в систему, то копия каждого утра попадёт на ваш диск в тот же день. Если вы ещё не писали cron-выражений, пять полей разобраны в статье Cron expressions explained, а scheduled tasks worth having подскажет, что ещё стоит поставить на эту вкладку.

Следите за числом слотов. Игровой тариф с двумя слотами для бэкапов работает с ротацией: когда оба заняты, запланированный бэкап заменяет самый старый незаблокированный. Здесь это не страшно - ваш ПК хранит историю, для которой в панели нет места. Это же лучший довод в пользу скачивания: два слота на сервере, четырнадцать дней на вашем диске.

Проверка того, что копии пригодны#

Файл с правильным именем и размером ещё не бэкап. «Бэкап, который никто не восстанавливал, - это гипотеза», и то же относится к скачанному. Скрипт уже прочитывает каждый архив от начала до конца, что ловит оборванные загрузки и повреждённые потоки gzip. Это первый уровень.

Второй уровень - заглянуть внутрь. Раз в месяц берите самый свежий архив и просматривайте его содержимое:

code
tar -tzf C:\ServerBackups\a1b2c3d4\2026-10-16_0500-3f9a1c2e.tar.gz | more

Вы проверяете, что папка мира, конфигурационные файлы и данные плагинов на месте и не подозрительно малы. Если мира нет, прежде чем искать причину где-то ещё, посмотрите .pteroignore.

Третий уровень - настоящее восстановление, и только оно что-то доказывает. Распакуйте архив в пустую папку и запустите из неё сервер - на своём ПК, если игра там запускается, или на запасном сервере. Как это сделать, не трогая рабочий сервер, показано в статье Testing a restore before you need it, а backups that actually restore описывает сбои, которые проявляются только на этом шаге.

Как уберечь локальную копию#

Копия на ПК остаётся копией «в стороне», только пока она отделена от того, что может навредить серверу.

  • Не синхронизируйте её обратно в облако напрямую. Папка с бэкапами внутри OneDrive или Dropbox годится как третья копия, но клиенты синхронизации зеркалируют удаления. Если шифровальщик или неудачный скрипт опустошит папку, пустая папка и синхронизируется. Используйте историю версий или держите синхронизируемую копию отдельно от папки, куда скачиваются архивы.
  • Раз в неделю делайте офлайн-копию. Внешний диск, который вы подключаете, копируете на него и отключаете, - единственная копия, до которой не доберётся шифровальщик на вашем ПК. robocopy C:\ServerBackups E:\ServerBackups /E делает это одной строкой.
  • Берегите ключ. API-ключ может всё то, что может ваш аккаунт на серверах, к которым у него есть доступ. По возможности ограничьте его по адресу, держите в переменной окружения, а не в скрипте, и отзовите в панели, если ПК потерян.
  • Следите за диском. Игровые архивы растут вместе с миром. Посмотрите размер папки после первых двух недель и поправьте $Keep, пока диск не заполнился, а не после.

Если вы предпочитаете, чтобы копия лежала не на вашем ПК, тот же приём работает с объектным хранилищем: этот путь описан в статьях game server backups to S3 и rclone with S3 storage.

Если скачивание не работает#

Скрипт пишет по одной строке на архив в pull.log в папке бэкапов сервера, а Task Scheduler хранит результат последнего запуска задачи. По ним большинство сбоев легко локализовать.

  • 401 или 403 от API. Ключ неверный, отозван или ограничен адресом, с которого вы не заходите. Проверьте ключ в новом окне командой echo $env:RENODE_API_KEY; если вывод пуст, значит, setx выполнен, а эта сессия запущена до него. Если вы ограничили ключ по IP, а адрес вашего подключения сменился, добавьте новый.
  • 404 на сервер. Короткий ID неверный, либо ключ принадлежит аккаунту, который не является ни владельцем, ни субпользователем этого сервера.
  • Задача показывает успех, но ничего не скачивается. Возможно, нового просто нет. Посмотрите вкладку Backups: если последний бэкап завершился ошибкой или ещё выполняется, скрипт по замыслу его пропускает.
  • Загрузка мучительно медленная. Убедитесь, что строка с $ProgressPreference на месте. Без неё Windows PowerShell 5.1 тратит большую часть времени на отрисовку индикатора прогресса.
  • Остаётся файл `.part`, а в логе строка BAD. Загрузка оборвалась или архив повреждён. Удалите файл .part; при следующем запуске он скачается заново. Если один и тот же бэкап не проходит каждый раз, создайте в панели новый и проверьте, пройдёт ли он.
  • «Running scripts is disabled on this system». Это политика выполнения. Задача передаёт -ExecutionPolicy Bypass для этого одного скрипта; при ручном запуске используйте тот же флаг, а не смягчайте политику для всей машины.
  • Задача не запускается, когда вы вышли из системы. Задачи, зарегистрированные так, работают только пока вы вошли в систему, - благодаря этому они читают вашу пользовательскую переменную окружения. Если нужно, чтобы задача выполнялась без вошедшего пользователя, зарегистрируйте её с сохранённым паролем и перенесите ключ в файл, доступный для чтения только этой учётной записи.

FAQ#

Можно ли скачать ночные бэкапы, которые делает RE:NODE?

Нет. Ночные системные бэкапы наши, мы храним их на случай инцидентов, и во вкладке Backups они скрыты. Восстановление из такого бэкапа выполняется через поддержку. Бэкапы, которые можно скачать и которые забирает этот скрипт, - те, что лежат в ваших собственных слотах.

Есть ли официальное приложение RE:NODE для бэкапов?

Нет. У нас действительно есть внутренняя программа, которая каждый день забирает копии с ноды для платформы, но клиентам она не предоставляется. Скрипт из этой статьи выполняет ту же работу для ваших серверов инструментами, которые уже есть в Windows.

Входит ли в скачанный архив моя база данных?

Нет. Архив бэкапа сервера - это файлы сервера. Слот базы данных - отдельная сущность, и ему нужен собственный дамп. Запишите дамп в файлы сервера до запуска бэкапа, и он окажется внутри архива, который вы скачиваете.

Сколько копий хранить на ПК?

Столько, чтобы можно было откатиться за момент, когда проблему заметили. Гриферство, повреждённый чанк или неудачный плагин часто обнаруживают спустя дни, поэтому неделя - минимум, а две недели - с комфортным запасом. Обычно единственное ограничение - место на диске.

Замедлит ли скачивание бэкапов мой сервер?

Нет. Скачивание читает уже существующий архив из хранилища бэкапов; игровой сервер в этом не участвует. Создание самого бэкапа требует некоторой нагрузки на диск и CPU ноды, поэтому назначайте его на тихое время.

Можно ли использовать это на Mac или Linux?

Идея переносится напрямую - два запроса к API, загрузка, tar -tzf, шаг хранения, - но сам скрипт написан на PowerShell, а планировщик - это Windows. В Linux или macOS эквивалентом будет короткий shell-скрипт с curl и запись в cron.

Это было полезно?