Build Your Own Palworld Server, Part 2: The Save Trap, Safe Shutdown, and Backups
Published 2026-07-13 · SameOS Tools
Part 1 got the server up with friends connected. This part covers three traps I actually hit while running it - the config file that loses its settings when edited the wrong way, the shutdown that silently throws away progress, and the backups that cover you when something still goes wrong. Each takes five minutes to prevent once you know it; not knowing can cost you the whole world.
The Config File Ownership Trap
World settings (rates, player caps and so on) live in Saved/Config/LinuxServer/PalWorldSettings.ini inside the data folder. The trap: the container manages this file under its own internal account with mode 600 (only the owner can read or write). If you replace the file from the terminal (cp, mv), the owner changes to your account and the server may fail to read it or reset it on the next start. Overwriting the contents in place (cat new.ini > PalWorldSettings.ini) preserves ownership. Changes apply after a restart, and copying the file aside first gives you an instant rollback.
Always Save Before Stopping - the SIGTERM Trap
This is where you can lose the most. The stock Palworld launch script does not reliably forward the termination signal (SIGTERM - the signal Linux sends a program to say "clean up and exit") to the game, so depending on how your image is built, docker stop can become a force-kill without saving - I actually lost progress since the last autosave this way. Check your image's documentation for graceful-shutdown support, but with any image the surest method is saving explicitly before stopping. The safe order is announce → save → shutdown. Run the commands below in the server terminal; the final shutdown takes a wait time, which also gives your friends a moment to log off.
# 0) go to the working folder and load the passwords from .env
cd ~/palworld
export $(grep -v '^#' .env | xargs)
# 1) announce to connected players
curl -u admin:$ADMIN_PASSWORD -H "Content-Type: application/json" \
-d '{"message":"Server restarting in 5 minutes"}' \
http://127.0.0.1:8212/v1/api/announce
# 2) save the world
curl -u admin:$ADMIN_PASSWORD -X POST http://127.0.0.1:8212/v1/api/save
# 3) shut down after 30s - a bare docker stop discards the save
curl -u admin:$ADMIN_PASSWORD -H "Content-Type: application/json" \
-d '{"waittime":30,"message":"Server shutting down"}' \
http://127.0.0.1:8212/v1/api/shutdown
Automatic Backups, and One compose Trap
For backups, archiving the world save folder (SaveGames) with tar (the standard Linux command that bundles files into one archive) is enough - register it in cron (the built-in Linux scheduler) once a day and auto-delete old archives. And one compose trap: if a helper container in the same compose file declares depends_on the game server, redeploying the helper silently resurrects a game server you had deliberately stopped. I hit this and removed it. With restart: unless-stopped, crashes recover automatically while manual stops are respected.
#!/bin/bash
# backup script - register in cron once a day (e.g. 15 5 * * *)
cd "$HOME/palworld"
mkdir -p backups
tar czf backups/world-$(date +%Y%m%d-%H%M).tar.gz \
-C palworld-data/Pal/Saved SaveGames
find backups -name 'world-*.tar.gz' -mtime +14 -delete # keep two weeks
With these three in place the server runs for weeks without incident. Typing terminal commands for every save and restart still gets old, though. In part 3 we replace all of it with buttons on a self-built browser admin page.