Выделенный сервер Project Zomboid на VPS через SteamCMD
Установка сервера Build 42 на Debian 12 / Ubuntu 24.04: SteamCMD, лимит памяти Java, servertest.ini, UDP-порты 16261–16262, служба systemd со screen, обновление без validate и бэкапы мира.

Собственный сервер Project Zomboid работает круглосуточно, а вы решаете, сколько будет игроков, включён ли PVP и кто может зайти. Ниже — установка выделенного сервера через SteamCMD, ограничение памяти, порты, автозапуск с безопасной остановкой и резервные копии. Проверено на Debian 12 с Build 42.21; на Ubuntu 24.04 команды те же.
Как устроен сервер
Сервер Project Zomboid — бесплатная программа, которую Valve раздаёт через Steam под номером приложения 380870. Купленная игра и аккаунт Steam не нужны: SteamCMD скачивает её анонимно. Сервер приносит свою Java 25 в папке jre64, отдельно её ставить не надо.
Файлы игры лежат в папке сервера, а мир, учётные записи, настройки и логи — в папке Zomboid в домашней папке пользователя. Поэтому обновление через SteamCMD не трогает ваш мир.
Игроки подключаются по UDP: порт 16261 для Steam-запросов, 16262 для RakNet. Нужны оба. Если порты закрыты, сервер просто молчит — пакеты до него не доходят.
Главный ресурс — память. В ProjectZomboid64.json по умолчанию стоит -Xmx8g; для небольшого VPS это много, ставим 3 ГБ. Процесс при этом занимает лимит плюс ~0,9 ГБ служебной памяти Java, и в простое не освобождает её (используется ZGC). Считайте с запасом.
Build 42 и Build 41. Ветка
publicв SteamCMD сейчас содержит Build 42. Есть веткиunstable,legacy41(Build 41.78.21) и42.19. Выбор — параметром-beta, например+app_update 380870 -beta legacy41 validate. Версия клиента у игроков должна совпадать с версией сервера. Перед сменой ветки делайте копию мира.
Что нужно
- Сервер на tanaka.host с Debian 12 или Ubuntu 24.04, не меньше 6 ГБ памяти (при
-Xmx3gпроцесс берёт ~4 ГБ) и ~7 ГБ на диске. На 4 ГБ сервер стартует с-Xmx2g, но запас небольшой. - Доступ по SSH под root — Подключение по SSH.
- Игра у каждого игрока той же версии, что сервер.
1. Библиотеки и пользователь
SteamCMD — 32-битная программа, на 64-битной системе ей нужны две библиотеки. Заодно ставим screen для консоли:
apt update
apt install -y screen curl ca-certificates lib32gcc-s1 lib32stdc++6
Отдельный пользователь zomboid с домашней папкой /opt/zomboid:
useradd -r -m -d /opt/zomboid -s /bin/bash zomboid
2. SteamCMD
Шаги 2–5 выполняются от пользователя zomboid:
su - zomboid
mkdir ~/steamcmd && cd ~/steamcmd
curl -fsSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar zxf -
Это маленький загрузчик, остальное докачается при первом запуске.
3. Загрузка сервера
Анонимный вход и установка приложения 380870 в /opt/zomboid/server:
./steamcmd.sh +force_install_dir /opt/zomboid/server +login anonymous +app_update 380870 validate +quit
Скачивается ~2 ГБ, на диске занимает ~7 ГБ, уходит несколько минут. В конце — Success! App '380870' fully installed. В папке сервера появятся start-server.sh, jre64 и ProjectZomboid64.json.
4. Лимит памяти
Замените 8 ГБ на 3 ГБ (на сервере с 4 ГБ — -Xmx2g):
sed -i 's/-Xmx8g/-Xmx3g/' ~/server/ProjectZomboid64.json
grep Xmx ~/server/ProjectZomboid64.json
Должно вывести "-Xmx3g",. Остальное в файле не трогайте.
validateсбрасывает этот параметр. Запуск SteamCMD сvalidateвозвращаетProjectZomboid64.jsonк исходному виду, и лимит снова станет 8 ГБ. Как обновляться без этого — ниже.
5. Первый запуск вручную
При первом старте сервер спрашивает пароль администратора, поэтому запускаем руками:
cd ~/server
./start-server.sh
После строк загрузки появятся Enter new administrator password и Confirm the password. Введите пароль дважды — сервер создаст учётную запись admin. Пароль при вводе виден на экране открытым текстом: не делайте скриншотов и не используйте параметр -adminpassword в скрипте запуска, иначе он останется в файле.
Затем сервер создаёт мир (около минуты). Когда появится SERVER STARTED, введите quit — мир сохранится, сервер завершится. Вернитесь в root:
exit
Что появилось в /opt/zomboid/Zomboid:
| Путь | Содержимое |
|---|---|
Server/servertest.ini |
основные настройки |
Server/servertest_SandboxVars.lua |
правила мира: зомби, смена дня и ночи |
Saves/Multiplayer/servertest |
сам мир |
db/servertest.db |
учётные записи игроков |
Logs |
журналы |
servertest — имя сервера по умолчанию, по нему называются все файлы.
6. Настройки servertest.ini
Правьте только при остановленном сервере — при запуске он переписывает файл:
nano /opt/zomboid/Zomboid/Server/servertest.ini
| Параметр | По умолчанию | Значение |
|---|---|---|
PublicName |
My PZ Server | имя в списках |
Password |
пусто | пароль для входа |
MaxPlayers |
32 | лимит игроков, админы не считаются |
PVP |
true | игроки могут ранить друг друга |
Open |
true | вход без заранее созданной учётки |
Public |
false | показывать в публичном списке |
PauseEmpty |
true | время стоит, пока никого нет |
SaveWorldEveryMinutes |
0 | периодичность сохранения |
UPnP |
true | поиск роутера; на VPS ставьте false |
Разумный набор для сервера с друзьями:
PublicName=Friends Server
Password=ваш_пароль
MaxPlayers=8
PVP=false
UPnP=false
SaveWorldEveryMinutes=15
Для строгого контроля поставьте Open=false и создавайте учётки сами командой adduser Имя Пароль в консоли сервера.
7. Порты 16261 и 16262
Именно UDP:
ufw allow 16261:16262/udp
Для firewalld: firewall-cmd --permanent --add-port=16261-16262/udp && firewall-cmd --reload. Подробнее — Брандмауэр UFW и firewalld.
Проверять нужно с другого компьютера. Скрипт на Python 3 шлёт стандартный Steam-запрос A2S_INFO; сохраните как pz-check.py:
import socket, sys
host, port = sys.argv[1], 16261
req = b"\xff\xff\xff\xffTSource Engine Query\x00"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(3)
try:
s.sendto(req, (host, port))
data, _ = s.recvfrom(4096)
if data[4:5] == b"A": # сервер просит повторить запрос с проверочным кодом
s.sendto(req + data[5:9], (host, port))
data, _ = s.recvfrom(4096)
print("Сервер отвечает, имя:", data[6:data.index(0, 6)].decode())
except socket.timeout:
print("Ответа нет, порт закрыт или сервер не запущен")
python3 pz-check.py IP-адрес-сервера
Если скрипт печатает имя сервера — порт доступен из интернета.
8. Автозапуск через systemd
Сервер будет жить внутри screen, чтобы в консоль можно было зайти. Скрипт остановки отправляет quit и ждёт завершения:
nano /opt/zomboid/stop.sh
#!/bin/sh
# Отправляет команду quit в консоль сервера и ждёт, пока сервер сохранит мир и завершится
screen -p 0 -S zomboid -X stuff "quit$(printf '\r')"
while kill -0 "$MAINPID" 2>/dev/null; do sleep 1; done
chmod +x /opt/zomboid/stop.sh
chown zomboid:zomboid /opt/zomboid/stop.sh
nano /etc/systemd/system/zomboid.service
[Unit]
Description=Project Zomboid server
After=network-online.target
Wants=network-online.target
[Service]
User=zomboid
WorkingDirectory=/opt/zomboid/server
ExecStart=/usr/bin/screen -DmS zomboid /opt/zomboid/server/start-server.sh
ExecStop=/opt/zomboid/stop.sh
Restart=always
RestartSec=10
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now zomboid
systemctl status zomboid
Сервер загружается около 40 секунд. Дальше — только через systemd: systemctl stop zomboid сохраняет мир и выключает, restart перезапускает, start включает. start-server.sh завершается с кодом 0 даже после падения Java, поэтому нужен именно Restart=always. Из этого следует, что quit в консоли тоже приведёт к перезапуску, а не к выключению.
Игровые сообщения в journalctl не попадают: сервер пишет их в консоль внутри screen. Логи — в /opt/zomboid/Zomboid/Logs, последний запуск — в /opt/zomboid/Zomboid/server-console.txt.
9. Консоль и подключение игроков
su - zomboid -c "screen -r zomboid"
Выход без остановки: Ctrl+A, затем D. Полезные команды:
| Команда | Действие |
|---|---|
players |
кто подключён |
save |
сохранить мир сейчас |
servermsg "Текст" |
сообщение всем |
adduser Имя Пароль |
создать учётку игрока |
quit |
сохранить и остановить (служба запустит снова) |
Игроки вводят IP сервера, порт 16261, пароль сервера (если задан), затем имя и пароль персонажа. На открытом сервере учётка создаётся при первом входе. Администратор — имя admin и пароль из шага 5.
Обновление сервера
Клиенты обновляются через Steam сами, версия сервера должна совпадать. Скрипт останавливает сервер, обновляет, возвращает лимит памяти и запускает:
nano /usr/local/bin/zomboid-update.sh
#!/bin/sh
# Останавливает сервер, обновляет его через SteamCMD, возвращает лимит памяти и запускает снова
systemctl stop zomboid
su - zomboid -c "~/steamcmd/steamcmd.sh +force_install_dir /opt/zomboid/server +login anonymous +app_update 380870 +quit"
su - zomboid -c "sed -i 's/-Xmx[0-9]*[gGmM]/-Xmx3g/' /opt/zomboid/server/ProjectZomboid64.json"
systemctl start zomboid
chmod +x /usr/local/bin/zomboid-update.sh
zomboid-update.sh
validate в скрипте нет намеренно: обычное обновление не трогает изменённый ProjectZomboid64.json, а проверка файлов — возвращает 8 ГБ. validate нужен только для ремонта повреждённых файлов; после него повторите шаг 4.
Резервные копии
Сервер сам кладёт копии в /opt/zomboid/Zomboid/backups (по умолчанию 5, параметр BackupsCount), но на том же диске. Свой скрипт: команда save, архив мира, учёток и настроек в /opt/zomboid/archives, 7 последних:
nano /opt/zomboid/backup.sh
#!/bin/sh
# Сохраняет мир, архивирует его вместе с настройками и хранит 7 последних архивов
cd /opt/zomboid || exit 1
screen -p 0 -S zomboid -X stuff "save$(printf '\r')"
sleep 10
mkdir -p archives
tar -czf "archives/zomboid-$(date +%F-%H%M).tar.gz" Zomboid/Saves Zomboid/db Zomboid/Server
ls -1t archives/zomboid-*.tar.gz | tail -n +8 | xargs -r rm --
chmod +x /opt/zomboid/backup.sh
chown zomboid:zomboid /opt/zomboid/backup.sh
echo "0 4 * * * /opt/zomboid/backup.sh" | crontab -u zomboid -
Архивы регулярно уносите с сервера — см. Резервные копии VPS. Восстановление:
systemctl stop zomboid
su - zomboid -c "tar -xzf /opt/zomboid/archives/ИМЯ-АРХИВА.tar.gz -C /opt/zomboid"
systemctl start zomboid
Частые ошибки
| Симптом | Причина и решение |
|---|---|
./steamcmd.sh: cannot execute: required file not found |
Нет 32-битных библиотек. Шаг 1. |
Служба active, порты не слушаются, в консоли Enter new administrator password |
Первый запуск ждёт пароль. systemctl stop zomboid, шаг 5 вручную, quit, снова systemctl start. |
ERROR: ld.so: object 'libjsig.so' …, Property Name not found: ladderW |
Безвредно, если дальше есть SERVER STARTED. |
If the server hangs here, set UPnP=false |
Сервер ищет роутер. UPnP=false в servertest.ini — запуск станет быстрее. |
| Нет ответа снаружи | systemctl status zomboid, ufw status, ss -ulpn | grep 1626. Правило должно быть для UDP. |
Killed process (ProjectZomboid6) в journalctl -k |
OOM: уменьшите -Xmx или возьмите сервер с большей памятью. |
| После обновления снова 8 ГБ | Запускали с validate. Повторите шаг 4, обновляйтесь скриптом. |