Project Zomboid is an open-world zombie survival game from The Indie Stone, and its dedicated server runs natively on Linux. A dedicated server keeps your group's world persistent and running whether or not the host is online.
In this tutorial you will install the Project Zomboid dedicated server on Ubuntu 24.04 with SteamCMD, create the server and its admin account, configure the server and sandbox settings, add Steam Workshop mods, run it as a systemd service that saves cleanly on shutdown, and set up backups.
Prerequisites
To follow this tutorial, you will need:
- A server running Ubuntu 24.04, for example a CubePath VPS. Plan for at least 2 vCPUs and 8 GB of RAM for a small group; heavily modded servers or more than 10 players need 16 GB.
- At least 20 GB of free disk space.
- A non-root user with
sudoprivileges and UFW enabled. - Project Zomboid on Steam to connect to the server.
Step 1 - Installing SteamCMD
SteamCMD is Valve's command-line client for downloading dedicated servers. Ubuntu ships it in the multiverse repository, and it needs 32-bit libraries, so enable both:
sudo dpkg --add-architecture i386
sudo add-apt-repository -y multiverse
sudo apt update
Install SteamCMD:
sudo apt install -y steamcmd
During the installation you are asked to accept the Steam license. Use the arrow keys and Enter to accept it. The binary is installed as /usr/games/steamcmd.
Step 2 - Creating a dedicated user
Run the server under an unprivileged account without a password. You access it from your admin user with sudo:
sudo adduser --disabled-password --gecos "" pzserver
sudo -iu pzserver
whoami
pzserver
Step 3 - Downloading the server
As the pzserver user, download the dedicated server (Steam app ID 380870) into ~/server:
/usr/games/steamcmd +force_install_dir /home/pzserver/server +login anonymous +app_update 380870 validate +quit
When the download finishes you should see:
Success! App '380870' fully installed.
The server runs on Java, and the Java runtime is bundled with it, so you don't need to install one.
Step 4 - Running the server for the first time
The first start creates the configuration files and asks you to set the password of the built-in admin account. Every server has a name, which prefixes its configuration files; this tutorial uses main. Start it in the foreground:
cd ~/server
./start-server.sh -servername main
When prompted, enter and confirm a strong password for the admin account. The server then generates the world. Wait until a line containing SERVER STARTED appears, then type quit and press Enter to stop it cleanly.
The configuration files are now in ~/Zomboid/Server/:
ls ~/Zomboid/Server/
main.ini main_SandboxVars.lua main_spawnregions.lua
| File | Contents |
|---|---|
main.ini | Server settings: name, password, player limit, PvP, mods |
main_SandboxVars.lua | World rules: zombie population and behavior, loot, day length, utilities shutoff |
main_spawnregions.lua | Towns where new characters can spawn |
The world save is stored in ~/Zomboid/Saves/Multiplayer/main/ and the player accounts in ~/Zomboid/db/main.db.
Step 5 - Configuring the server settings
Open the server settings:
nano ~/Zomboid/Server/main.ini
The file has one Key=Value setting per line. Change these and leave the rest as they are:
PublicName=Your Server Name
PublicDescription=Your server description
Public=true
Password=your_server_password
MaxPlayers=16
PVP=false
PauseEmpty=true
SaveWorldEveryMinutes=15
DefaultPort=16261
UDPPort=16262
Public=truelists the server in the in-game browser. Withfalse, players join by IP address.Passwordis the password to join; leave it empty for an open server. Each player also creates their own account on first join, protected by the password they choose.PauseEmpty=truestops the game clock while nobody is online, so zombies don't overrun bases overnight.SaveWorldEveryMinutessets how often the world is saved automatically.
Sandbox options control the difficulty. They are easier to set in the game: in Project Zomboid, go to Host > Manage Settings, create settings with the sandbox options you like, and then copy the generated <settings_name>_SandboxVars.lua from Zomboid/Server/ on your PC over ~/Zomboid/Server/main_SandboxVars.lua on the server. You can also edit the file directly; each option has a comment explaining its values.
ImportantMost sandbox options only apply when the world is created. To apply new sandbox settings to an existing server, you have to start a new world by deleting
~/Zomboid/Saves/Multiplayer/main/.
Type exit to return to your admin user.
Step 6 - Adding Workshop mods (optional)
The server downloads Steam Workshop mods on startup. Each mod needs two identifiers, both listed on its Workshop page: the Workshop ID (the number in the page URL) and the Mod ID (in the description, usually near the bottom). Add them to main.ini, separated by semicolons:
WorkshopItems=2169435993;2392709985
Mods=modoptions;tsarslib
The values above are only examples of the format. Some Workshop items contain several mods; add every Mod ID you want to enable. Clients download the same mods automatically when they join. After adding mods, restart the server and check the log for download or loading errors.
Step 7 - Opening the firewall ports
Project Zomboid uses two UDP ports:
sudo ufw allow 16261:16262/udp
sudo ufw status
Step 8 - Creating the systemd service
The server only saves cleanly when it receives the save and quit commands on its console, so simply killing the process can lose progress. To send commands to the server while it runs as a service, you give it a named pipe (FIFO) as its console input: systemd creates the pipe with a socket unit, and anything you write to it reaches the server console.
Create the socket unit:
sudo nano /etc/systemd/system/zomboid.socket
[Unit]
BindsTo=zomboid.service
[Socket]
ListenFIFO=/home/pzserver/zomboid.control
FileDescriptorName=control
RemoveOnStop=true
SocketMode=0660
SocketUser=pzserver
Create the service unit:
sudo nano /etc/systemd/system/zomboid.service
[Unit]
Description=Project Zomboid dedicated server
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=pzserver
Group=pzserver
WorkingDirectory=/home/pzserver/server
Sockets=zomboid.socket
ExecStart=/bin/sh -c "exec /home/pzserver/server/start-server.sh -servername main < /home/pzserver/zomboid.control"
ExecStop=/bin/sh -c "echo save > /home/pzserver/zomboid.control; sleep 15; echo quit > /home/pzserver/zomboid.control"
KillSignal=SIGCONT
TimeoutStopSec=120
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
How it works:
- The server reads its console from the FIFO instead of a terminal.
- On
systemctl stop,ExecStopwritessave, waits for the save to finish and then writesquit. KillSignal=SIGCONTstops systemd from terminating the Java process while it is still saving. If the server has not exited afterTimeoutStopSec, systemd kills it.
Reload systemd and start the service:
sudo systemctl daemon-reload
sudo systemctl enable --now zomboid
sudo systemctl status zomboid
Follow the log until the server is up:
sudo journalctl -u zomboid -f
Wait for the SERVER STARTED line, then press Ctrl+c to stop following the log. Check the ports:
sudo ss -ulnp | grep java
You should see UDP sockets on ports 16261 and 16262. To join, open Project Zomboid, choose Join, and enter your_server_ip with port 16261 and the server password. Pick a username and password for your character account.
Step 9 - Sending admin commands
To run a console command, write it to the FIFO. The output appears in the journal:
echo "players" | sudo tee /home/pzserver/zomboid.control > /dev/null
sudo journalctl -u zomboid -n 20
Useful console commands:
| Command | What it does |
|---|---|
players | List connected players |
setaccesslevel "username" admin | Give a player admin rights |
servermsg "message" | Broadcast a message to everyone |
kickuser "username" | Kick a player |
banuser "username" | Ban a player |
save | Save the world |
quit | Save and stop the server |
You can also log in from the game with the admin account and the password you set in Step 4, or give your own character admin rights with setaccesslevel and use the same commands prefixed with / in the in-game chat.
Use sudo systemctl stop zomboid rather than sending quit yourself: a manual quit ends the process outside systemd's stop sequence.
Step 10 - Backing up the world
Back up the save, the configuration and the player database once a day. Create a backup directory and open the pzserver user's crontab:
sudo -u pzserver mkdir -p /home/pzserver/backups
sudo -u pzserver crontab -e
Add these lines. They save the world, wait a minute, archive the data and remove archives older than 7 days:
0 5 * * * echo save > /home/pzserver/zomboid.control
1 5 * * * tar -czf /home/pzserver/backups/zomboid-$(date +\%F).tar.gz -C /home/pzserver Zomboid/Saves Zomboid/Server Zomboid/db
30 5 * * * find /home/pzserver/backups -name 'zomboid-*.tar.gz' -mtime +7 -delete
The % is escaped because cron treats a bare % as a newline. To restore, stop the service, extract the archive into /home/pzserver with tar -xzf, and start the service again.
Updating the server
Clients must run the same build as the server. To update:
sudo systemctl stop zomboid
sudo -u pzserver /usr/games/steamcmd +force_install_dir /home/pzserver/server +login anonymous +app_update 380870 validate +quit
sudo systemctl start zomboid
Your configuration and saves live in ~/Zomboid/, outside the installation directory, so updates do not touch them. Workshop mods are updated automatically when the server starts.
Troubleshooting
The server runs out of Java memory with many mods or players. The Java heap limit is set by the -Xmx value in /home/pzserver/server/ProjectZomboid64.json. Raise it (for example to -Xmx12g), keeping a few GB free for the system, and restart the service.
Players are refused with a Workshop mod version mismatch. A mod was updated on Steam after the server started. Restart the server so it downloads the new version.
The service hangs when stopping. Check that /home/pzserver/zomboid.control exists while the service runs and that the zomboid.socket unit is active with systemctl status zomboid.socket.
Players cannot connect. Check that UFW allows 16261:16262/udp, that the server printed SERVER STARTED, and that the client and server builds match.
Conclusion
You now have a Project Zomboid dedicated server on Ubuntu 24.04, running as a systemd service that saves before stopping, with custom server and sandbox settings, Workshop mods, a console you can reach through a named pipe, and daily backups.
As next steps, fine-tune main_SandboxVars.lua before starting a new world, make the server invite-only by setting Open=false in main.ini and creating accounts for your players with the adduser "username" "password" console command, and copy your backups off the server.
