Files
minecraft-lab/docs/backups.md
T
2026-10-04 00:30:09 +07:00

119 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Backup и восстановление — Phase 5
`./mcpack backup` работает с полным релизом и runtime, который уже связан
с ним через `scripts/server.sh`. Нужны Node/npm dependencies, закреплённый
Compose, Docker daemon, GNU tar и zstd. Оператор должен читать весь runtime
и сохранять владельцев при распаковке: запускать от владельца данных или
с необходимыми правами. Проверка UID/GID не пропускается.
## Создание snapshot
```bash
export MC_ROOT=/absolute/server-root
export MC_RELEASE_DIR=/absolute/full-release
# MC_ENV_FILE — необязательный абсолютный путь, по умолчанию MC_ROOT/.env.
./mcpack backup --wait-timeout 120
```
Команда удерживает общую `.mcpack-runtime.lock`, проверяет релиз/settings,
останавливает сервер через Compose и подтверждает остановку по Docker state.
После этого архивирует **весь `MC_ROOT/runtime` без исключений**: world,
данные модов вне world, конфиги, server.properties, whitelist/operators,
логи, cache, downloads и установленные server/mod JAR. Для NeoForge безопасные
исключения пока не подтверждены. Releases, snapshots и host `.env` находятся
вне runtime и не входят в архив; внутри snapshot хранится отдельная полная
копия исходного релиза, включая его `.env.example`.
Результат находится в `MC_ROOT/backups/<UTC timestamp>-<UUID>/`:
```text
runtime.tar.zst
metadata.json
SHA256SUMS
release/ # исходный полный релиз с собственными checksums
```
Metadata фиксирует исходный релиз, SHA256 manifest/checksum list, закреплённый
image, целевой релиз (если передан `--target-release /absolute/release`),
прежнее состояние сервера, подтверждение остановки, время, исключения,
архив SHA256/размер и inventory путей/хешей/размеров/mode/UID/GID runtime.
`--target-release` только проверяет и записывает назначение будущего deployment;
команда backup сама не применяет новый релиз.
Перед публикацией выполняются tar/zstd listing, проверка типов/путей и
пробная распаковка с точным сравнением inventory. Checksums покрывают все
файлы snapshot и сохранённого релиза. Каталог публикуется атомарным rename
внутри backups; незавершённый snapshot не появляется под окончательным именем.
При успехе ранее запущенный сервер возвращается на тот же релиз через
`up --wait`. Остановленный сервер или отсутствующий контейнер не запускаются.
Ошибка backup возвращает non-zero. При ошибке после успешной остановки сервер
остаётся остановленным; оператор получает ошибку и status в
`MC_ROOT/.mcpack-backup-operation.json`. Ошибка resume сохраняет опубликованный
проверенный snapshot и пытается снова остановить сервер. Новый deployment
должен использовать `backupBeforeApply` из `platform/backups.mjs`: callback
применения допускается только после публикации snapshot и под той же блокировкой.
Этот gate проверен тестами и используется SSH deployment Phase 7 под общей
блокировкой всей операции: [deploy.md](deploy.md).
Snapshot не удаляется автоматически. Нужны свободное место под полный runtime,
пробную распаковку и копию релиза; операция завершается ошибкой при нехватке места.
Символические/жёсткие ссылки и специальные файлы в runtime сейчас отклоняются.
Команды вне wrapper не участвуют в блокировке; во время backup не изменять
runtime вручную и не запускать контейнер прямым Compose.
## Восстановление в отдельный каталог
```bash
./mcpack restore \
--backup /absolute/server-root/backups/TIMESTAMP-UUID \
--destination /absolute/restored-server
```
Destination должен **не существовать**. Команда сначала проверяет snapshot,
распаковывает во временный соседний каталог, сверяет bytes/mode/UID/GID,
проверяет сохранённый релиз и публикует новый root атомарным rename.
Исходный runtime не изменяется. Результат:
```text
restored-server/runtime/
restored-server/release/
restored-server/.mcpack-runtime.json
restored-server/restore-report.json
```
Host settings и EULA acceptance из snapshot не восстанавливаются; сервер
автоматически не запускается. Для ручного recovery подготовить `.env` из
`release/server/.env.example`, задать прежние UID/GID, подходящие memory/port
и принятие EULA. Используется прежний стабильный Compose project из binding.
Прежде чем запускать восстановленную копию под тем же project, остановить
и удалить **старый контейнер** через wrapper (данные старого root сохраняются):
```bash
MC_ROOT=/absolute/original-server \
MC_RELEASE_DIR=/absolute/original-release scripts/server.sh down
# На данном host settings уже настроены и EULA принята:
export MC_ROOT=/absolute/restored-server
export MC_RELEASE_DIR="$MC_ROOT/release"
export MC_ENV_FILE=/absolute/prepared-host-settings.env
scripts/server.sh up -d --wait --wait-timeout 120
scripts/server.sh exec -T minecraft mc-health
scripts/server.sh logs --tail 100
```
Не заменять binding или release на более новую версию: восстановленный мир
нужно запускать с сохранённым исходным релизом. Если прежний контейнер ещё
использует другой root, wrapper отклонит запуск. Это ручное восстановление
в отдельный root; переключение active release и rollback — последующие фазы.
## Область проверки
Проверен local Linux/WSL Docker и NeoForge 21.1.252 / Minecraft 1.21.1.
Primary Phase 0 runtime пока управляется старым spike wrapper без full-release
binding, поэтому его миграция не выполняется этой командой. Off-host копии,
retention, автоматический rollback и защита от внезапного отключения питания
во время записи (fsync) остаются последующими улучшениями.
Реальный опыт восстановления и свидетельства: [phase5-results.md](phase5-results.md).