Workflow CI гоняет gofmt, vet, тесты и сборку на каждый push в main; workflow Release по тегу v* собирает бинарники под linux/amd64 и arm64, считает контрольные суммы и публикует релиз через API Gitea. Оба workflow забирают код через git, а не actions/checkout: это JS-действие, которому нужен Node внутри контейнера, а в образе golang его нет. Заодно сборка перестала зависеть от доступности github.com, что для self-hosted инстанса существенно. Скрипт deploy/get.sh ставит последний релиз одной командой: определяет архитектуру, забирает файлы релиза, сверяет sha256 (бинарник ставится с правами root) и передаёт управление install.sh. Обновление — та же команда. Версия сборки попадает в бинарник через ldflags, доступна как `pzmanager version` и видна в панели на вкладке «Настройки»: без неё нельзя понять, какой релиз стоит на сервере. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PZ Manager
Веб-панель для управления выделенным сервером Project Zomboid на Ubuntu. Один бинарник без зависимостей: веб-интерфейс вшит внутрь, Node.js и Python на сервере не нужны.
Что умеет
- Профили серверов — несколько независимых сборок (свой мир, конфиг, песочница, моды и лимит памяти) с переключением одной кнопкой.
- Управление сервером — запуск, остановка (через команду
quit, мир сохраняется), перезапуск, автоподъём после падения, автозапуск вместе с менеджером. - Живая консоль — вывод сервера в реальном времени и отправка любых команд
(
players,save,servermsg,kickuser, …). - Мониторинг — состояние, аптайм, CPU и память процесса сервера, свободные ОЗУ и диск на хосте, список игроков онлайн.
- Редактор конфигов —
servertest.iniиSandboxVars.luaпрямо в браузере, с поиском по параметрам и сохранением комментариев в файле. - Мод-менеджер — моды списком с галочками и перетаскиванием порядка загрузки, добавление по ссылке и разворачивание коллекций Steam целиком.
- Бэкапы — ручные и по расписанию, отдельно по каждому профилю, с ротацией, скачиванием и восстановлением (перед восстановлением автоматически снимается страховочная копия).
- Установка и обновление сервера через SteamCMD прямо из панели.
Как это устроено
Менеджер запускает start-server.sh как дочерний процесс и держит его stdin,
stdout и stderr. Отсюда следует всё остальное: команды консоли пишутся прямо в
stdin (RCON не нужен), логи стримятся в браузер через SSE, а остановка идёт по
цепочке quit → SIGTERM → SIGKILL для всей группы процессов.
Сам менеджер живёт под systemd, который его и перезапускает.
systemd ──> pzmanager ──> start-server.sh ──> java (GameServer)
│
├── HTTP + SSE ──> браузер
└── SteamCMD, бэкапы, конфиги
Быстрый старт
На чистом Ubuntu/Debian всё ставится одной командой — она возьмёт последний релиз, проверит контрольные суммы и настроит systemd:
curl -fsSL https://gitea.hsrv.site/mrleo1nid/pzmanager/raw/branch/main/deploy/get.sh | sudo bash
По умолчанию панель слушает 127.0.0.1:8080 — только с самой машины. Чтобы
она была доступна в локальной сети, укажите адрес сервера:
curl -fsSL https://gitea.hsrv.site/mrleo1nid/pzmanager/raw/branch/main/deploy/get.sh \
| sudo PZ_LISTEN=10.10.1.142:8080 bash
Переменные: PZ_LISTEN (адрес панели), PZ_HOME (каталог, по умолчанию
/opt/pzmanager), PZ_USER (системный пользователь), PZ_VERSION
(конкретный тег вместо последнего).
Скрипт запускается от root, так что перед первым запуском его разумно прочитать: deploy/get.sh.
Установщик поставит зависимости (SteamCMD, JRE, SDL2), заведёт пользователя
pzserver без shell, положит бинарник в /usr/local/bin и создаст структуру:
/opt/pzmanager/
├── config.yaml настройки менеджера
├── data/ учётки панели и скачанный SteamCMD
├── server/ серверные файлы Project Zomboid
├── Zomboid/ миры, конфиги и логи игры
└── backups/ архивы
Обновление — та же команда: конфиг, миры и учётные записи не трогаются, меняется только бинарник.
Дальше:
-
Посмотрите код первичной настройки:
journalctl -u pzmanager -n 30 --no-pager -
Откройте панель в браузере и создайте администратора, введя этот код. Если панель слушает localhost, пробросьте порт:
ssh -L 8080:127.0.0.1:8080 пользователь@сервер -
Во вкладке «Обзор» нажмите Установить / обновить через SteamCMD и дождитесь окончания — прогресс виден во вкладке «Консоль».
-
Запустите сервер. При первом запуске PZ создаст
Zomboid/Server/*.ini— после этого станут доступны вкладки «Конфиг сервера», «Песочница» и «Моды».
Порты, которые нужно открыть:
sudo ufw allow 8080/tcp # веб-панель, если она слушает не localhost
sudo ufw allow 16261/udp # игровой порт
sudo ufw allow 16262/udp # второй игровой порт
Установка из исходников
Если релизам предпочитаете свою сборку (нужен Go 1.24+, собирать можно на любой ОС, включая Windows):
make build-linux
Скопируйте pzmanager и папку deploy/ на сервер и запустите установщик:
sudo PZ_LISTEN=10.10.1.142:8080 ./deploy/install.sh
Моды
Project Zomboid хранит моды в двух строках конфига: WorkshopItems — что
скачать из мастерской, Mods — что включить и в каком порядке. Панель
показывает их одним списком, где каждая строка — мод:
- галочка включает мод (добавляет его Mod ID в
Mods); - перетаскивание (или стрелки) задаёт порядок загрузки — для модов, которые переопределяют одни и те же файлы, он решает, чья версия победит;
- «Убрать» выбрасывает пакет из
WorkshopItemsвместе со всеми его модами.
Добавить мод можно ссылкой на страницу мастерской или голым ID. Кнопка «Добавить коллекцию» разворачивает коллекцию в список входящих в неё модов — порядок берётся тот же, что на странице коллекции.
Mod ID, который нужен серверу, лежит внутри самого мода (mod.info), поэтому
панель читает уже скачанные моды с диска:
<server_dir>/steamapps/workshop/content/108600/<workshop id>/mods/<мод>/mod.info
~/Zomboid/mods/<мод>/mod.info # моды, положенные вручную
Пока сервер не скачал мод, его строка помечена «ещё не скачан» и галочка
недоступна: Mod ID неизвестен. Файлы загружает сам сервер при запуске по
списку WorkshopItems — то есть достаточно добавить моды, сохранить и
запустить сервер, после чего они станут доступны для включения.
Один пакет мастерской может содержать несколько модов — в списке они идут отдельными строками, и включать их можно по отдельности.
Профили серверов
Профиль — это отдельный сервер: свой мир, свой *.ini, свои настройки
песочницы, свой список модов и свой лимит памяти. Project Zomboid различает их
по параметру -servername, поэтому профили не мешают друг другу:
~/Zomboid/Server/vanilla.ini ~/Zomboid/Saves/Multiplayer/vanilla/
~/Zomboid/Server/vanilla_SandboxVars.lua
~/Zomboid/Server/modded.ini ~/Zomboid/Saves/Multiplayer/modded/
~/Zomboid/Server/modded_SandboxVars.lua
Работает всегда один профиль — активный: серверные файлы, игровые порты и файл запуска JVM общие. Переключить профиль можно на остановленном сервере, выбрав его в шапке панели или на вкладке «Профили»; после этого все вкладки — конфиг, песочница, моды, бэкапы — относятся уже к нему.
При создании профиля можно скопировать .ini и настройки песочницы из
существующего: удобно, когда нужен тот же набор правил, но чистый мир.
Удаление профиля убирает его только из панели — мир и конфиги остаются на диске. Чтобы вернуть профиль, создайте его с тем же идентификатором.
Обновление с версии, где сервер был один, проходит само: старые поля
server_name, admin_password и java_memory превращаются в первый профиль
при первом запуске.
Доступ снаружи
Панель управляет сервером, поэтому наружу её лучше не выставлять голой. Два разумных варианта:
SSH-туннель (по умолчанию) — ничего настраивать не нужно, панель слушает только localhost.
Доверенная локальная сеть — PZ_LISTEN=<ip>:8080 при установке или
listen в конфиге. Учтите, что HTTP не шифруется: пароль от панели идёт по
сети открытым текстом, так что для доступа через интернет этот вариант не
годится.
HTTPS через reverse-proxy — если панель нужна с телефона. Настройте nginx с сертификатом (например, от Let's Encrypt):
server {
listen 443 ssl;
server_name pz.example.com;
ssl_certificate /etc/letsencrypt/live/pz.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pz.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# Живая консоль работает через Server-Sent Events.
proxy_buffering off;
proxy_read_timeout 24h;
}
}
И запустите менеджер с флагом --secure-cookies, чтобы cookie сессии
передавалась только по HTTPS (добавьте флаг в ExecStart юнита).
Команды
pzmanager serve # запустить панель (команда по умолчанию)
pzmanager useradd <логин> # создать пользователя панели
pzmanager passwd <логин> # сменить пароль
pzmanager users # список пользователей
Флаги: --config <путь>, --listen <адрес>, --secure-cookies.
Конфигурация
Файл /opt/pzmanager/config.yaml создаёт установщик (при запуске без него
менеджер возьмёт ~/.config/pzmanager/config.yaml). Всё, что в нём есть,
правится и через вкладку «Настройки».
listen: 127.0.0.1:8080 # адрес веб-панели; 0.0.0.0 или IP — доступ по сети
data_dir: /opt/pzmanager/data
server_dir: /opt/pzmanager/server # куда SteamCMD ставит сервер
zomboid_dir: /opt/pzmanager/Zomboid # миры, конфиги и логи игры
steamcmd_path: "" # пусто — найти в PATH или скачать
profiles: # серверы: у каждого свой мир и настройки
- id: vanilla # vanilla -> vanilla.ini, Saves/Multiplayer/vanilla
title: Ванильный мир # как профиль подписан в панели
admin_password: "" # пароль админа игрового сервера
java_memory: 4g # -Xmx для JVM этого профиля
extra_args: [] # доп. аргументы start-server.sh
- id: modded
title: Сборка с модами
java_memory: 8g
active_profile: vanilla # какой профиль запускается и настраивается
autostart: false # поднимать сервер вместе с менеджером
autorestart: true # поднимать сервер после падения
stop_timeout: 1m30s # сколько ждать после quit до SIGTERM
log_buffer_lines: 5000 # строк консоли в памяти
backup:
dir: /opt/pzmanager/backups
schedule: 6h # 0 — отключить автобэкапы
keep: 20 # архивов на профиль
stop_server: false # останавливать сервер на время бэкапа
Изменения listen применяются после systemctl restart pzmanager; остальные —
при следующем запуске игрового сервера.
Бэкапы
В архив попадают мир активного профиля и его серверные конфиги. Имя файла —
pz-профиль-ГГГГММДД-ЧЧММСС[-пометка].tar.gz, так что архивы разных сборок не
путаются, а ротация (backup.keep) считается по каждому профилю отдельно.
Архивы, снятые до появления профилей, панель тоже читает и восстанавливает.
Бэкап на живом сервере технически корректен, но снимок может отставать от
состояния мира в памяти. Если хочется гарантированной согласованности —
включите backup.stop_server (игроков на время бэкапа выкинет) или отправляйте
save в консоль перед ручным бэкапом.
Восстановление требует остановленного сервера. Перед распаковкой менеджер сам
делает страховочную копию с пометкой pre-restore.
Безопасность
- Пароли пользователей панели хранятся в виде bcrypt-хешей в
data_dir/users.json(права 0600). - Сессии живут только в памяти: перезапуск менеджера разлогинивает всех.
- Первого администратора можно создать только с одноразовым кодом из журнала.
- Изменяющие запросы требуют собственный заголовок — это защита от CSRF.
- Панель не выполняет произвольные команды хоста: всё, что она умеет, — это управление процессом сервера, SteamCMD и файлами в своих директориях.
Тем не менее доступ к панели равносилен доступу к игровому серверу, так что пароль стоит выбрать не короче того, что вы поставили бы на SSH.
Сборка и релизы
Репозиторий собирается Gitea Actions (.gitea/workflows):
- CI — на каждый push и pull request в
main:gofmt,go vet, тесты, проверка сборки под Linux и синтаксиса скриптов установки. - Release — на тег
v*: собирает бинарники подlinux/amd64иlinux/arm64, считает контрольные суммы и публикует релиз с ними и скриптами установки.
Выпуск новой версии:
git tag -a v1.2.3 -m "Описание релиза" && git push origin v1.2.3
Версия попадает в бинарник через -ldflags -X main.version= и видна в
pzmanager version и в панели на вкладке «Настройки».
Workflow не зависят от github.com и от Node внутри контейнера: код забирается
через git, а релиз публикуется прямо в API Gitea. Токен Actions выдаёт сам;
если в настройках инстанса его права урезаны, заведите секрет RELEASE_TOKEN
с доступом на запись в репозиторий.
Для работы Actions нужен зарегистрированный runner с меткой ubuntu-latest,
умеющий запускать контейнеры (docker).
Разработка
make test # тесты
make vet # go vet
make run # локальный запуск с конфигом в ./dev
Веб-интерфейс — обычные HTML, CSS и JS в web/static, без сборщика; при
go build они вшиваются в бинарник через embed.
Лицензия
MIT — делайте с кодом что угодно, но без каких-либо гарантий.