Factorio Руководство

Сохранения headless Factorio: резервная копия и восстановление

Копия данных и модов Factorio, хранение вне VPS и проверка выбранного сохранения в изолированной среде.

Сохранения headless Factorio: резервная копия и восстановление

Для восстановления Factorio нужен не только свежий ZIP. Сохраните фабрику, окружение модов, точную версию игры и конфигурацию, с которой можно снова запустить нужный мир. Затем проверьте внешнюю копию отдельно от работающего сервера.

Статья продолжает установку headless-сервера на Ubuntu: служба и пользователь factorio, исполняемый файл /opt/factorio/bin/x64/factorio, данные /srv/factorio. Нужны Bash, sudo, GNU tar, Python 3 и уже работающая установка Factorio 2.x. До выполнения команд сверяйте пути со своей установкой. Для согласованной копии мы остановим игру.

Определите состав восстановления#

В каталоге данных важны не только saves: сохраните config.ini, настройки сервера, моды с их настройками, списки доступа и собственные сценарии. Справочник каталогов разделяет установку игры и пользовательские данные. Если конфигурация или аргументы запуска ссылаются на файлы за пределами /srv/factorio, добавьте их отдельно и запишите исходные пути.

Рядом с архивом держите установщик той же версии headless. Номер версии говорит, что понадобится, но не гарантирует доступность загрузки в будущем. Для модифицированной фабрики сохраните установленные ZIP модов: актуальные выпуски не заменяют прежнее окружение. Здесь мы готовим резервную копию; переход между версиями разобран в статье о совместимости.

Автосохранения циклически перезаписываются. Они помогают вернуть недавний прогресс, но погибнут вместе с диском. Интервал и число слотов задайте в server-settings.json установленной версии; поля описаны в шаблоне Wube. Экспериментальное неблокирующее сохранение не заменяет процедуру согласованного копирования.

Архив — кандидат для восстановления. Загрузка конкретного сохранения из отдельно распакованной копии проверяет, есть ли в нём пригодная фабрика.

Остановите игру штатно#

Предупредите игроков о перерыве и остановите существующую службу:

bash
sudo systemctl stop factorio
sudo systemctl show factorio -p ActiveState -p SubState -p Result
sudo journalctl -u factorio -n 100 --no-pager

Убедитесь, что процесс завершился, а журнал содержит завершённое сохранение. Документация headless описывает сохранение при выходе; принудительное завершение и тайм-аут остановки не дают той же уверенности. Если служба завершилась с ошибкой, диск заполнен или сохранение не удалось, сохраните доступные файлы, но не считайте их последним состоянием фабрики. Другой supervisor не должен запускать процесс во время архивирования.

Следующий блок выполните в одной сессии Bash. mktemp создаёт новый закрытый каталог, не перезаписывая предыдущую копию:

bash
(
set -e
sudo install -d -o root -g root -m 700 /var/backups/factorio
backup_dir=$(sudo mktemp -d /var/backups/factorio/backup-XXXXXXXX)
sudo sh -c '/opt/factorio/bin/x64/factorio --version > "$1/version.txt"' sh "$backup_dir"
sudo tar -czf "$backup_dir/runtime.tar.gz" -C /srv factorio
sudo chmod 600 "$backup_dir/runtime.tar.gz" "$backup_dir/version.txt"
sudo tar -tzf "$backup_dir/runtime.tar.gz" >/dev/null
sudo sha256sum "$backup_dir/runtime.tar.gz"
printf '%s\n' "$backup_dir"
)

Продолжайте только после успешного выполнения каждой команды. Проверьте наличие нужных сохранений и настроек в архиве, запишите выбранный для восстановления ZIP и контрольную сумму. Читаемый список архива ещё не доказывает совместимость с игрой. Верните рабочую службу командой sudo systemctl start factorio и проверьте журнал: дальше используется уже снятая копия.

Вынесите проверенную копию с VPS#

Перенесите runtime.tar.gz, version.txt и соответствующий установщик в закрытое хранилище на другой машине. Подойдут зашифрованное хранилище резервных копий или передача по SSH: настройки могут содержать учётные данные. Для SSH сначала создайте временную копию архива с владельцем вашей учётной записи и правами 600, скачайте её, сравните SHA-256 на обеих сторонах и удалите временный файл. Не открывайте всем доступ к /var/backups/factorio ради скачивания.

Храните несколько поколений, включая состояние до обновления игры. Срок хранения выбирайте по доступному месту и допустимой потере прогресса. Успешная загрузка нового архива в хранилище ещё не основание удалять единственную проверенную старую копию.

Распакуйте в новый каталог#

Используйте собственный доверенный архив. В переменную archive введите абсолютный путь к внешней копии после возвращения на машину. Блок не должен продолжаться, если каталог восстановления уже существует:

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

bash
(
set -e
read -r -p "Absolute archive path: " archive
sudo test -f "$archive"
sudo python3 - "$archive" <<'PYARCHIVE'
import sys
import tarfile
from pathlib import PurePosixPath
with tarfile.open(sys.argv[1], 'r:gz') as archive:
    for member in archive.getmembers():
        path = PurePosixPath(member.name)
        if path.is_absolute() or '..' in path.parts:
            raise SystemExit('Unsafe archive path')
        if not (member.isfile() or member.isdir()):
            raise SystemExit('This restore example requires regular files and directories')
PYARCHIVE
sudo mkdir -m 750 /srv/factorio-restore
sudo tar --no-same-owner -xzf "$archive" -C /srv/factorio-restore
sudo chown -R factorio:factorio /srv/factorio-restore
sudo -u factorio tee /srv/factorio-restore/factorio/config.ini >/dev/null <<'CONFIG'
[path]
read-data=/opt/factorio/data
write-data=/srv/factorio-restore/factorio
CONFIG
)

В /opt/factorio должна находиться соответствующая версия игры. Если рабочий сервер уже обновлён, используйте отдельную сохранённую установку и исправьте read-data. Проверьте распакованные настройки: другие абсолютные пути тоже не должны вести в рабочие данные. Создайте тестовые настройки без публикации в общем списке и LAN:

bash
sudo -u factorio python3 - <<'PY'
import json
from pathlib import Path
root = Path('/srv/factorio-restore/factorio')
settings = json.loads((root / 'server-settings.json').read_text())
settings['visibility'] = {'public': False, 'lan': False}
for key in ('username', 'password', 'token'):
    settings[key] = ''
(root / 'restore-settings.json').write_text(json.dumps(settings, indent=2))
PY

Выберите настоящий ZIP из восстановленного saves. Вместо CHOSEN.zip укажите его имя; автоматический выбор последнего файла для этой проверки не нужен:

bash
sudo -u factorio /opt/factorio/bin/x64/factorio \
  --config /srv/factorio-restore/factorio/config.ini \
  --mod-directory /srv/factorio-restore/factorio/mods \
  --start-server /srv/factorio-restore/factorio/saves/CHOSEN.zip \
  --server-settings /srv/factorio-restore/factorio/restore-settings.json \
  --bind 127.0.0.1 --port 34198

Предварительно убедитесь, что порт 34198 свободен. Этот процесс работает в текущем терминале и доступен только локально; правило firewall для него не открывайте. Проверьте ошибки загрузки и остановите Ctrl+C. Успешная загрузка полезна, но саму фабрику тоже осмотрите в локальном клиенте нужной версии, используя отдельную копию сохранения: знакомое место, исследования, недавние постройки.

Для восстановления рабочего сервера остановите его, сохраните текущее состояние и явно выберите восстановленный ZIP по инструкции выбора мира. Подключитесь и проверьте сохранность изменений после штатного перезапуска. Внешнюю копию до завершения проверки оставьте неизменной.

При нескольких экземплярах панель для собственного VPS помогает организовать операции. Адрес внешнего хранилища и проверку восстановления закрепите в своей процедуре обслуживания.