Moving an Existing Minecraft World to Google Cloud
Checking an existing world archive, staging it on the VM, replacing the test world, connecting, and creating a new backup
Check an existing Java Edition world’s archive paths and level.dat, then extract it into a
temporary directory on the VM. After the checks, stop the server, replace
the world in one step, and put the old test world back if the start fails.
Prerequisites
You must have finished the backup and the isolated load test for the Google Cloud test world in part 06. The source server you are moving from must also be able to shut down cleanly.
Verification scope
The archive check and the rollback branch were tested in an Ubuntu container. No personal world was uploaded to a real VM or swapped in. The current state is
local and container verification complete, real Google Cloud apply unverified.
The Source Server and the World Folder
Copying while the source server writes files can mix chunks from different points in time. Disconnect the players and shut the source Minecraft server down cleanly. Copy the world folder after the Java process exits.
level.dat must sit directly inside the folder.
world/
├── level.dat
├── region/
├── data/
├── playerdata/
├── DIM-1/
└── DIM1/
There must not be an extra folder level, as in world/world/level.dat. If that is what you have,
the migration target is the inner world folder that directly contains level.dat, not the outer one.
Move the inner folder somewhere else, such as the desktop, and build the archive below from that
folder. On a Paper-family server where the Nether and End are separate top-level folders, do not
merge them with this vanilla example. Check how your server implementation lays out dimensions and
plan that move separately.
Creating world.tar.gz
In Windows PowerShell, move to the parent directory of the world folder and run the commands
there. The parent directory is the location where File Explorer shows the world folder. Click the
File Explorer address bar, copy the path, and paste it after cd. If the server folder is
C:\my-server, for example, run cd C:\my-server first.
Conditional run: Windows
tar -czf world.tar.gz world
tar -tf world.tar.gz | Select-Object -First 20
On macOS or Linux, run it in the same location.
Conditional run: macOS or Linux
tar -czf world.tar.gz world
tar -tf world.tar.gz | sed -n '1,20p'
The first path in the listing should be world/, and world/level.dat should appear. Do not put
the source server.properties, whitelist, or operator list into this archive. That keeps the Google
Cloud server’s whitelist and port settings in place.
Checking the Archive in Cloud Shell
Open Cloud Shell in the Google Cloud Console and click Upload in the three-dot menu at the top
right. Select the world.tar.gz you just created. When the upload finishes, move to the server
example directory.
Run
cd "${HOME}/minecraft-one-root"
scripts/validate-world-archive.sh \
"${HOME}/world.tar.gz" \
world
The check rejects absolute paths, .., symbolic links, hard links, device files, and any other
top-level folder. It also fails when world/level.dat is missing. A normal result shows the
expected extracted size and the SHA-256.
Do not copy the archive to the VM when an error appears. Fix the source folder structure, build a new archive, and start again from the check.
Copying to VM Staging
Read the VM name and zone from the Terraform outputs and send the archive to /tmp.
Run
export MINECRAFT_INSTANCE="$(
terraform output -raw minecraft_instance_name
)"
export MINECRAFT_ZONE="$(
terraform output -raw minecraft_zone
)"
gcloud compute scp \
"${HOME}/world.tar.gz" \
"${MINECRAFT_INSTANCE}:/tmp/world.tar.gz" \
--zone="${MINECRAFT_ZONE}"
If the transfer breaks, run the same command again and then compare the hash on the VM.
Check
export LOCAL_SHA="$(
sha256sum "${HOME}/world.tar.gz" | cut -d' ' -f1
)"
export REMOTE_SHA="$(
gcloud compute ssh "${MINECRAFT_INSTANCE}" \
--zone="${MINECRAFT_ZONE}" \
--command="sha256sum /tmp/world.tar.gz" | cut -d' ' -f1
)"
printf 'local %s\nremote %s\n' "${LOCAL_SHA}" "${REMOTE_SHA}"
[[ "${LOCAL_SHA}" == "${REMOTE_SHA}" ]] \
&& echo "SHA-256 OK" \
|| echo "SHA-256 MISMATCH"
Instead of eyeballing two 64-character values, read SHA-256 OK on the last line. On MISMATCH, do
not replace anything; run gcloud compute scp again.
Replacing the Production World
This command uses minecraft-world-archive-check installed on the VM to rerun the archive check you
ran in Cloud Shell, against the same criteria. Repeating the check confirms that the validated
archive structure is still present after upload. It then extracts into a temporary directory and
fails before stopping the server when there is not enough free disk space. Only after the check
passes does it move the current test world into a rollback directory.
Run: this replaces the production world
gcloud compute ssh "${MINECRAFT_INSTANCE}" \
--zone="${MINECRAFT_ZONE}" \
--command="sudo minecraft-world-import \
/tmp/world.tar.gz \
world"
If the file move, the ownership change, the service start, or the is-active check fails, the
script clears the imported world away and puts the previous test world back. If errors appear during
the rollback as well, do not run more move commands; record the current listing of /srv/minecraft
and the systemd log.
The Done Log and the First Connection
Check: up to 10 minutes
gcloud compute ssh "${MINECRAFT_INSTANCE}" \
--zone="${MINECRAFT_ZONE}" \
--command='
active_since="$(
systemctl show minecraft \
--property=ActiveEnterTimestamp \
--value
)"
for attempt in $(seq 1 60); do
sudo journalctl \
-u minecraft \
--since "${active_since}" \
--no-pager |
grep -q "Done (.*)! For help" && exit 0
sudo systemctl is-active --quiet minecraft || exit 1
sleep 10
done
exit 1
'
If the command fails, read the first error from sudo journalctl -u minecraft -n 200 --no-pager. Do
not open a world in an older JAR once a newer version has opened it. On a version mismatch, prepare
the Minecraft version and Java major that last ran the source correctly, using the procedure in
part 08, and move the world
again.
Once Done appears, connect with the operator account you registered in part 05. Check the coordinates you
wrote down before the move, along with chest contents, signs, and player inventories. The whitelist
and ops.json keep the Google Cloud server’s existing settings.
A New Backup Right After the Move
Once the connection check is done, back up the new state.
Run
gcloud compute ssh "${MINECRAFT_INSTANCE}" \
--zone="${MINECRAFT_ZONE}" \
--command="sudo systemctl start minecraft-backup.service"
Find the new archive name the same way as in part 06 and run minecraft-backup-verify. Do not
delete the source server or the source archive until the new archive passes the isolated load test.
Delete the temporary upload file on the VM after the new backup is verified.
Deletes data: the temporary file on the VM, after the new backup is verified
gcloud compute ssh "${MINECRAFT_INSTANCE}" \
--zone="${MINECRAFT_ZONE}" \
--command="sudo rm -- /tmp/world.tar.gz"
Completion Check
- You created the archive after shutting the source server down cleanly.
- The archive check and the SHA-256 comparison between local and VM both passed.
- You saw
Done (...)!with the new world. - You checked the recorded coordinates and the player data yourself.
- The backup made right after the move passed the isolated load test.
- You kept the source world and archive until the new backup was verified.
After verifying the new backup, use Minecraft Server Power and Version Changes for VM stops and JAR replacement.
Comments
No comments yet. Be the first to leave one.
Pending review