Автозапуск игрового сервера через systemd и cron
Настройка автозапуска игрового сервера через systemd и cron на Linux: unit-файл, скрипт-обёртка, логи journald, корректное завершение.
Кратко: Systemd unit-файл с Restart=on-failure обеспечивает автозапуск и авторестарт игрового сервера при падении. Для простых случаев подходит @reboot cron. Логи читаются через journalctl без дополнительных инструментов.
Автозапуск игрового сервера через systemd и cron
Каждый раз вручную запускать игровой сервер после перезагрузки VPS - неэффективно и ненадёжно. В 2026 году стандартный подход для Linux-серверов - systemd с unit-файлом, который берёт на себя запуск, мониторинг и авторестарт при падении. Альтернатива - @reboot cron - проще в настройке, но не поддерживает нативный авторестарт. В этой статье разберём оба метода на конкретных примерах: Minecraft, CS2, Project Zomboid и других игровых серверов, плюс скрипт-обёртку для дополнительной надёжности.
Pterohost - игровой хостинг с NVMe-дисками, DDoS-защитой и поддержкой 24/7. Серверы управляются через панель Pterodactyl без ручной настройки systemd. Промокод 4START даёт -20% на первый заказ. Заказать Minecraft хостинг
Почему systemd лучше простого скрипта в rc.local
До появления systemd администраторы использовали /etc/rc.local, init-скрипты или cron @reboot. Эти методы работают, но у них есть ограничения:
- Нет встроенного авторестарта при падении процесса
- Сложно управлять зависимостями (например, запустить сервер только после монтирования диска или поднятия сети)
- Логи разбросаны по разным файлам или вообще теряются
- Нет удобного способа проверить статус сервиса
Systemd решает все эти проблемы и является стандартом в Debian 10+, Ubuntu 20.04+, CentOS 8+, Fedora и большинстве современных дистрибутивов.
Проверка что systemd используется в системе
ps -p 1 -o comm=
Если вывод systemd - вы на современной системе. Если init или runit - используйте @reboot cron или init-скрипты.
Создание systemd unit-файла для игрового сервера
Unit-файлы пользовательских сервисов хранятся в /etc/systemd/system/. Имя файла станет именем сервиса.
Базовый unit-файл для Minecraft сервера
Создайте файл /etc/systemd/system/minecraft.service:
[Unit]
Description=Minecraft Java Edition Server
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/usr/bin/java -Xmx4G -Xms1G -jar server.jar nogui
ExecStop=/bin/kill -s SIGTERM $MAINPID
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minecraft
[Install]
WantedBy=multi-user.target
Разберём ключевые директивы:
| Директива | Значение |
|---|---|
After=network.target | Запуск только после инициализации сети |
User=minecraft | Запуск от непривилегированного пользователя |
WorkingDirectory= | Рабочая директория для процесса |
ExecStart= | Команда запуска сервера |
Restart=on-failure | Перезапуск только при аварийном завершении (код != 0) |
RestartSec=10 | Пауза 10 секунд перед рестартом |
StandardOutput=journal | Перенаправить stdout в journald |
Включение и запуск сервиса
# Перечитать конфигурацию systemd после создания файла
systemctl daemon-reload
# Включить автозапуск при загрузке
systemctl enable minecraft
# Запустить сервис прямо сейчас
systemctl start minecraft
# Проверить статус
systemctl status minecraft
Unit-файл для CS2 сервера
CS2 требует SteamCMD и специфических параметров. Пример unit-файла:
[Unit]
Description=Counter-Strike 2 Dedicated Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=steam
Group=steam
WorkingDirectory=/opt/cs2/game/bin/linuxsteamrt64
ExecStart=/opt/cs2/game/bin/linuxsteamrt64/cs2 \
-dedicated \
-port 27015 \
+map de_dust2 \
+maxplayers 20
Restart=on-failure
RestartSec=15
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal
SyslogIdentifier=cs2-server
[Install]
WantedBy=multi-user.target
Директива LimitNOFILE=65536 увеличивает лимит открытых файлов - CS2 и другие игровые серверы при нагрузке открывают много сетевых соединений.
Unit-файл для Project Zomboid
Project Zomboid запускается через скрипт, поэтому ExecStart ссылается на него:
[Unit]
Description=Project Zomboid Server
After=network.target
[Service]
Type=simple
User=pzserver
Group=pzserver
WorkingDirectory=/opt/pzserver
ExecStart=/opt/pzserver/start-server.sh -servername MyServer
ExecStop=/opt/pzserver/stop-server.sh
Restart=on-failure
RestartSec=20
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pzserver
[Install]
WantedBy=multi-user.target
Корректное завершение сервера и сохранение данных
Один из ключевых аспектов - правильная остановка сервера. Если просто убить процесс через kill -9, данные последней сессии не сохранятся.
Настройка ExecStop для Minecraft
Minecraft слушает stdin, поэтому команду остановки можно передать через FIFO или screen/tmux. Более надёжный способ - использовать RCON:
[Service]
ExecStart=/usr/bin/java -Xmx4G -Xms1G -jar server.jar nogui
ExecStop=/usr/bin/mcrcon -H 127.0.0.1 -P 25575 -p yourpassword "say Server restarting in 10 seconds" "save-all" "stop"
TimeoutStopSec=60
KillMode=process
KillSignal=SIGTERM
Если RCON не настроен - используйте tmux:
[Service]
ExecStart=/usr/bin/tmux new-session -d -s minecraft -x 220 -y 50 \
'java -Xmx4G -Xms1G -jar /opt/minecraft/server.jar nogui'
ExecStop=/usr/bin/tmux send-keys -t minecraft 'say Server shutting down' Enter \
&& sleep 5 && /usr/bin/tmux send-keys -t minecraft 'save-all' Enter \
&& sleep 10 && /usr/bin/tmux send-keys -t minecraft 'stop' Enter
Type=forking
TimeoutStopSec=120
Важно: при использовании tmux тип сервиса меняется на Type=forking, так как tmux запускается в фоне.
Параметр TimeoutStopSec
По умолчанию systemd ждёт 90 секунд перед принудительным убийством процесса. Для тяжёлых серверов с большим миром (Minecraft, Project Zomboid) это время может быть недостаточным:
[Service]
TimeoutStopSec=300
Для серверов с большими мирами рекомендуется 3-5 минут.
Скрипт-обёртка с авторестартом
Если systemd недоступен или нужна дополнительная логика (уведомления в Telegram, проверка свободного места перед запуском), используйте скрипт-обёртку.
Создайте файл /opt/minecraft/start-with-watchdog.sh:
#!/bin/bash
# Конфигурация
SERVER_DIR="/opt/minecraft"
SERVER_JAR="server.jar"
JAVA_ARGS="-Xmx4G -Xms1G"
LOG_FILE="/var/log/minecraft/server.log"
MAX_RESTARTS=10
RESTART_DELAY=10
# Подготовка
mkdir -p "$(dirname $LOG_FILE)"
cd "$SERVER_DIR" || exit 1
restart_count=0
while true; do
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting server (attempt $((restart_count + 1)))..." | tee -a "$LOG_FILE"
# Проверка свободного места (минимум 1GB)
FREE_SPACE=$(df "$SERVER_DIR" | awk 'NR==2 {print $4}')
if [ "$FREE_SPACE" -lt 1048576 ]; then
echo "[$(date)] ERROR: Less than 1GB free space. Not starting." | tee -a "$LOG_FILE"
exit 1
fi
# Запуск сервера
java $JAVA_ARGS -jar "$SERVER_JAR" nogui >> "$LOG_FILE" 2>&1
EXIT_CODE=$?
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Server stopped with exit code $EXIT_CODE" | tee -a "$LOG_FILE"
# Если сервер завершился корректно (код 0) - не рестартуем
if [ $EXIT_CODE -eq 0 ]; then
echo "[$(date)] Clean exit. Not restarting." | tee -a "$LOG_FILE"
break
fi
restart_count=$((restart_count + 1))
if [ $restart_count -ge $MAX_RESTARTS ]; then
echo "[$(date)] Max restarts ($MAX_RESTARTS) reached. Giving up." | tee -a "$LOG_FILE"
exit 1
fi
echo "[$(date)] Restarting in ${RESTART_DELAY}s..." | tee -a "$LOG_FILE"
sleep "$RESTART_DELAY"
done
Сделайте скрипт исполняемым:
chmod +x /opt/minecraft/start-with-watchdog.sh
Unit-файл для скрипта-обёртки:
[Unit]
Description=Minecraft Server with Watchdog
After=network.target
[Service]
Type=simple
User=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/opt/minecraft/start-with-watchdog.sh
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
Автозапуск через cron @reboot
Для тех, кто не хочет создавать unit-файл, cron предоставляет простой механизм @reboot.
Добавление задачи @reboot
# Открыть crontab для пользователя gameserver
crontab -u gameserver -e
Добавьте строку:
@reboot /opt/minecraft/start-with-watchdog.sh > /var/log/minecraft/cron-startup.log 2>&1
Или без перенаправления (лог в /var/spool/mail):
@reboot cd /opt/minecraft && java -Xmx4G -Xms1G -jar server.jar nogui
Ограничения cron @reboot
| Параметр | systemd | cron @reboot |
|---|---|---|
| Авторестарт при падении | Да (Restart=on-failure) | Нет (только при загрузке) |
| Управление зависимостями | Да (After=, Wants=) | Нет |
| Централизованные логи | Да (journald) | Нет |
| Команда статуса | systemctl status | Только ps aux |
| Остановка | systemctl stop | kill PID вручную |
| Уведомления | Встроены | Только через скрипт |
Вывод: @reboot cron подходит для быстрого решения или при отсутствии systemd. Для продакшн-серверов используйте systemd.
Логи через journald
Journald - встроенная система логирования systemd, заменяющая syslog для сервисов. Все stdout/stderr вашего сервера попадают в журнал автоматически если в unit-файле указано StandardOutput=journal.
Основные команды journalctl
# Просмотр логов сервиса в реальном времени
journalctl -u minecraft -f
# Логи за последний час
journalctl -u minecraft --since "1 hour ago"
# Логи за конкретный день
journalctl -u minecraft --since "2026-06-05" --until "2026-06-06"
# Последние 100 строк
journalctl -u minecraft -n 100
# Только ошибки
journalctl -u minecraft -p err
# Экспорт в файл
journalctl -u minecraft --since today > /tmp/mc-log-today.txt
Настройка ротации логов journald
По умолчанию journald хранит логи до заполнения 10% диска. Для игровых серверов с высоким выводом можно ограничить:
# /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=7day
После изменения перезапустите journald:
systemctl restart systemd-journald
Несколько серверов на одной машине
Если на одном VPS запущено несколько игровых серверов, создайте отдельный unit-файл для каждого.
Пример для двух Minecraft серверов (выживание и хайпиксель):
# /etc/systemd/system/mc-survival.service
# /etc/systemd/system/mc-hypixel.service
Содержимое mc-survival.service:
[Unit]
Description=Minecraft Survival Server
After=network.target
[Service]
Type=simple
User=mc-survival
WorkingDirectory=/opt/servers/survival
ExecStart=/usr/bin/java -Xmx6G -Xms2G -jar paper.jar nogui
Restart=on-failure
RestartSec=10
StandardOutput=journal
SyslogIdentifier=mc-survival
[Install]
WantedBy=multi-user.target
Для управления:
systemctl start mc-survival
systemctl start mc-hypixel
systemctl status mc-survival mc-hypixel
# Логи обоих серверов одновременно
journalctl -u mc-survival -u mc-hypixel -f
Автоматические плановые рестарты
Игровые серверы рекомендуется перезапускать раз в 24 часа для очистки памяти и применения обновлений конфигов.
Через systemd timer (рекомендуется)
Создайте файл /etc/systemd/system/minecraft-restart.timer:
[Unit]
Description=Daily Minecraft Server Restart
Requires=minecraft-restart.service
[Timer]
OnCalendar=*-*-* 04:00:00
AccuracySec=1min
Persistent=true
[Install]
WantedBy=timers.target
И /etc/systemd/system/minecraft-restart.service:
[Unit]
Description=Restart Minecraft Server
After=minecraft.service
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart minecraft
Активация таймера:
systemctl enable --now minecraft-restart.timer
systemctl list-timers --all | grep minecraft
Через cron (альтернатива)
crontab -u root -e
# Рестарт Minecraft каждый день в 4:00
0 4 * * * /usr/bin/systemctl restart minecraft
Безопасность: запуск от непривилегированного пользователя
Никогда не запускайте игровой сервер от root. Создайте отдельного пользователя:
# Создать системного пользователя без домашней директории и входа
useradd -r -s /bin/false -d /opt/minecraft minecraft
# Создать директорию сервера и передать права
mkdir -p /opt/minecraft
chown -R minecraft:minecraft /opt/minecraft
В unit-файле:
[Service]
User=minecraft
Group=minecraft
# Ограничения безопасности
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/minecraft /var/log/minecraft
ProtectSystem=strict делает файловую систему доступной только для чтения, кроме явно указанных путей в ReadWritePaths. Это предотвращает запись в системные директории даже при компрометации сервера.
Связанные материалы
Для полноценного управления игровым сервером на Linux вам также могут пригодиться статьи по подключению к базам данных - Подключение к MySQL и Управление базами данных MySQL, где описаны настройка и работа с MySQL, которая используется плагинами типа LuckPerms и EssentialsX. Для передачи файлов конфигурации и обновления серверных ресурсов используйте FTP/SFTP-подключение - Подключение по FTP и SFTP.
Заключение
Systemd unit-файл с Restart=on-failure - это надёжный и современный способ обеспечить автозапуск игрового сервера на Linux. По сравнению с cron @reboot он даёт авторестарт при падении, удобные логи через journald и полноценное управление через systemctl. Скрипт-обёртка добавляет дополнительную логику: проверку ресурсов, лимит рестартов, уведомления. Для плановых ежедневных рестартов используйте systemd timer - он надёжнее cron и интегрирован с теми же логами. Главное - всегда запускайте сервер от непривилегированного пользователя и настройте корректное завершение через ExecStop, чтобы не терять данные мира.
Pterohost - игровой хостинг с автоматическим управлением серверами, DDoS-защитой и NVMe-дисками. Не нужно настраивать systemd вручную - панель Pterodactyl берёт это на себя. Промокод 4START даёт -20% на первый заказ. Заказать Minecraft хостинг