Как настроить автоматический рестарт сервера
1. Подготовка окружения и проверка доступа
Перед настройкой автозапуска убедитесь, что у вас есть полный доступ к выделенному серверу через SSH. В панели proxify.cloud (Proxmox VE) откройте консоль вашей виртуальной машины с Ubuntu или подключитесь по SSH с локальной машины.
ssh root@<IP-адрес_вашего_сервера>
Проверьте, где находится исполняемый файл сервера (обычно paper.jar, spigot.jar или fabric-server-launch.jar) и рабочая директория. Стандартный путь для игровых серверов на Ubuntu — /home/minecraft/server или /opt/minecraft. Дальше в инструкции используется путь /home/minecraft/server. Замените его на свой при необходимости.
ls -la /home/minecraft/server/
# Ожидаемый вывод: server.jar, start.sh, eula.txt, plugins/, world/
Убедитесь, что пользователь minecraft существует и имеет права на папку. Если сервер запускался от root — смените владельца:
chown -R minecraft:minecraft /home/minecraft/server
2. Создание скрипта управления запуском (start.sh)
Автоматический рестарт требует надежного скрипта запуска, который корректно обрабатывает сигналы остановки и перезапуска. Создайте или отредактируйте файл start.sh в директории сервера.
nano /home/minecraft/server/start.sh
Вставьте следующий контент. Параметры -Xms и -Xmx настройте под объем RAM вашего выделенного сервера на proxify.cloud (например, 8G, 16G, 32G). Флаг -XX:+UseG1GC рекомендуется для современных версий Minecraft (1.18+).
#!/bin/bash
# Путь к Java (проверьте: which java)
JAVA_PATH="/usr/bin/java"
# Память
HEAP_MIN="4G"
HEAP_MAX="8G"
# Файл сервера
SERVER_JAR="paper.jar"
# Имя сессии screen
SESSION_NAME="mcserver"
# Рабочая директория
WORK_DIR="/home/minecraft/server"
cd "$WORK_DIR" || exit 1
# JVM флаги оптимизации для Paper/Spigot
JVM_OPTS=(
-Xms${HEAP_MIN} -Xmx${HEAP_MAX}
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=40
-XX:G1HeapRegionSize=8M
-XX:G1ReservePercent=20
-XX:G1HeapWastePercent=5
-XX:G1MixedGCCountTarget=4
-XX:InitiatingHeapOccupancyPercent=15
-XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=5
-XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem
-Dusing.aikars.flags=https://mcflags.emc.gs
-Daikars.new.flags=true
)
# Запуск внутри screen для возможности подключения к консоли
exec ${JAVA_PATH} "${JVM_OPTS[@]}" -jar ${SERVER_JAR} --nogui
Сделайте скрипт исполняемым:
chmod +x /home/minecraft/server/start.sh
chown minecraft:minecraft /home/minecraft/server/start.sh
Важно: Тестовый запуск от пользователя minecraft:
su - minecraft -c "cd /home/minecraft/server && ./start.sh"
Убедитесь, что сервер стартует, мир загружается, и в консоли нет ошибок OutOfMemoryError или UnsupportedClassVersionError. Остановите сервер командой stop в консоли или Ctrl+C.
3. Настройка Systemd-юнита для автозапуска и рестарта
Systemd — стандартный менеджер служб в Ubuntu. Он обеспечит запуск при загрузке ОС, автоматический рестарт при краше и корректное завершение при перезагрузке хоста (через панель proxify.cloud).
Создайте файл юнита:
nano /etc/systemd/system/minecraft.service
Вставьте конфигурацию. Обратите внимание на User=minecraft, WorkingDirectory, ExecStart и политику Restart=on-failure.
[Unit]
Description=Minecraft Paper Server
Documentation=https://papermc.io/
After=network.target network-online.target
Wants=network-online.target
# Защита от запуска до монтирования дисков, если используется отдельный том
# RequiresMountsFor=/home/minecraft/server
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/home/minecraft/server
ExecStart=/home/minecraft/server/start.sh
# Перезапуск при краше (exit code != 0) или сигнале SIGSEGV/SIGABRT
Restart=on-failure
RestartSec=10
# Лимит на количество рестартов за интервал (защита от bootloop)
StartLimitIntervalSec=60
StartLimitBurst=3
# Корректная остановка: отправляем 'stop' в stdin процесса Java
ExecStop=/bin/bash -c 'echo "stop" | /usr/bin/screen -S mcserver -X stuff "$(printf \"stop\r\")"'
# Если stop не сработал за 30 сек — SIGKILL
TimeoutStopSec=30
KillSignal=SIGTERM
SendSIGKILL=yes
# Логирование в journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minecraft
# Ограничение ресурсов (опционально, для безопасности)
LimitNOFILE=65535
MemoryLimit=10G
CPUAccounting=yes
[Install]
WantedBy=multi-user.target
Пояснение по ExecStop: В данном примере предполагается, что вы используете screen внутри start.sh (см. шаг 2). Если вы запускаете Java напрямую без screen, замените ExecStop на:
ExecStop=/bin/bash -c 'echo "stop" > /home/minecraft/server/console.pipe'
И настройте named pipe во start.sh. Вариант с screen проще и надежнее для консольного доступа.
Перезагрузите конфигурацию systemd и включите автозапуск:
systemctl daemon-reload
systemctl enable minecraft.service
Запустите сервер через systemd и проверьте статус:
systemctl start minecraft.service
systemctl status minecraft.service
journalctl -u minecraft.service -f
4. Настройка планировщика (Cron) для ежедневного рестарта
Ежедневный рестарт (например, в 04:00 ночи) очищает утечки памяти, сбрасывает кэш чанков и предупреждает лаги. Лучше всего делать это через systemd-timer или cron. Используем cron для простоты и наглядности.
Откройте crontab от имени пользователя minecraft (не root, чтобы права на файлы мира не сломались):
crontab -u minecraft -e
Добавьте в конец файла:
# Ежедневный рестарт в 04:00 с предупреждением за 5, 1, 0.5 минуты
0 4 * * * /home/minecraft/server/restart_wrapper.sh >> /home/minecraft/server/logs/cron_restart.log 2>&1
Теперь создайте скрипт-обертку restart_wrapper.sh, который корректно предупредит игроков и перезапустит службу systemd. Прямой вызов systemctl restart из cron от пользователя minecraft не сработает без sudo (policykit). Поэтому используем подход с screen командой stop, а systemd поднимет процесс обратно благодаря Restart=on-failure (если мы убьем процесс) или лучше — используем systemctl через sudoers без пароля.
Вариант А: Через sudo (рекомендуется, чище)
Настройте sudoers для пользователя minecraft:
visudo -f /etc/sudoers.d/minecraft-restart
Добавьте строку:
minecraft ALL=(ALL) NOPASSWD: /bin/systemctl restart minecraft.service, /bin/systemctl stop minecraft.service, /bin/systemctl start minecraft.service
Теперь скрипт обертки /home/minecraft/server/restart_wrapper.sh:
nano /home/minecraft/server/restart_wrapper.sh
#!/bin/bash
# Скрипт мягкого рестарта с предупреждениями игроков
SESSION="mcserver"
SERVER_DIR="/home/minecraft/server"
LOG_FILE="${SERVER_DIR}/logs/restart_$(date +\%F).log"
# Функция отправки команды в консоль screen
send_cmd() {
/usr/bin/screen -S "$SESSION" -X stuff "$(printf "%s\r" "$1")"
}
echo "[$(date)] === Начало процедуры рестарта ===" | tee -a "$LOG_FILE"
# Предупреждение за 5 минут
send_cmd "say §e[Авторестарт] §fСервер перезагрузится через §c5 минут§f. Пожалуйста, завершите дела."
sleep 4m
# Предупреждение за 1 минуту
send_cmd "say §e[Авторестарт] §fСервер перезагрузится через §c1 минуту§f."
sleep 50s
# Предупреждение за 10 секунд
send_cmd "say §e[Авторестарт] §fСервер перезагрузится через §c10 секунд§f."
sleep 10s
# Сохранение мира
send_cmd "save-all"
send_cmd "save-off"
sleep 5
# Остановка через systemd (корректный SIGTERM -> stop -> SIGKILL)
echo "[$(date)] Отправка команды systemctl restart..." | tee -a "$LOG_FILE"
sudo /bin/systemctl restart minecraft.service
echo "[$(date)] Команда рестарта отправлена. Systemd поднимет сервер." | tee -a "$LOG_FILE"
Дайте права:
chmod +x /home/minecraft/server/restart_wrapper.sh
chown minecraft:minecraft /home/minecraft/server/restart_wrapper.sh
Вариант Б: Без sudo (через kill процесса Java)
Если не хотите настраивать sudoers, можно убить процесс Java, и systemd поднимет его заново (так как Restart=on-failure срабатывает и на SIGKILL/SIGTERM, если код возврата не 0). Но это "грубый" способ, мир может не успеть сохраниться (save-all отправляется, но нет гарантии завершения).
В restart_wrapper.sh замените строку systemctl restart на:
# Находим PID java процесса в конкретной screen сессии или по рабочей директории
PID=$(pgrep -f "java.*${SERVER_JAR}.*${WORK_DIR}")
if [ -n "$PID" ]; then
kill -TERM "$PID"
# Ждем 20 сек
sleep 20
# Если жив - убиваем принудительно
if kill -0 "$PID" 2>/dev/null; then
Комментарии (0)