Pterohost docs

Автозапуск игрового сервера через 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

Параметрsystemdcron @reboot
Авторестарт при паденииДа (Restart=on-failure)Нет (только при загрузке)
Управление зависимостямиДа (After=, Wants=)Нет
Централизованные логиДа (journald)Нет
Команда статусаsystemctl statusТолько ps aux
Остановкаsystemctl stopkill 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 хостинг