Свой сервер Minecraft - это не просто каприз энтузиаста, а вполне рабочий способ получить стабильный мир без случайных попутчиков и чужих правил. Сборка такого сервера на Ubuntu держится на нескольких опорных точках. Свежая Java, аккуратная подготовка системы, грамотно выставленные параметры JVM и служба systemd, которая поднимет процесс после перезагрузки. Каждый из этих слоёв влияет на то, как будет себя чувствовать мир при десяти игроках, двадцати чанках прогрузки и пачке модов сверху. Ниже разложен путь от голой Ubuntu до сервера, запускающегося сам собой после ребута.

Подготовка Ubuntu и выбор аппаратных ресурсов под будущий сервер Minecraft

Перед тем как что-то ставить, стоит честно взглянуть на железо. Ванильный сервер для пяти друзей уживётся в 2 ГБ оперативки, но как только появляются плагины, просторные миры и амбициозные постройки, аппетит Java растёт буквально на глазах. Практика показывает разумный ориентир. Для 1-5 игроков хватает 2 ГБ, для 5-15 нужны 4 ГБ, а сервер на 15+ человек с плагинами комфортно дышит от 8 ГБ и выше. Диск желателен SSD, потому что чанки постоянно пишутся и читаются, а классический HDD превращает сохранение мира в маленькое испытание для нервов.

Начало всегда одинаковое. Свежая система обновляется, чтобы не тащить за собой старые ошибки:

sudo apt update && sudo apt upgrade -y

Дальше желательно не сидеть под root. Если сервер арендуется у хостера и по умолчанию пускает root, стоит завести отдельного администратора с sudo и переключиться на него. Это скучный шаг, но он спасает от половины инцидентов в будущем.

Установка OpenJDK 21 как обязательного условия для современных версий игры

Minecraft 1.21 и всё, что вышло позже, требует Java 21. Попытка запустить такой сервер на Java 17 встретится с классической ошибкой UnsupportedClassVersionError, после чего процесс просто упадёт. Поэтому путь один - ставить OpenJDK 21 в безголовой серверной версии, без графических зависимостей.

sudo apt install -y openjdk-21-jre-headless curl wget screen

Пакет screen пригодится для живой консоли сервера, куда можно ввести команды вроде op, whitelist или say. Проверка идёт одной строкой:

java -version

Ответ должен содержать строку openjdk version "21.x.x". Если вместо 21 отобразилось что-то древнее, значит в системе уже жила другая сборка Java. Сменить выбранную по умолчанию помогает команда sudo update-alternatives --config java, где интерактивно выбирается нужный путь. Те, кто хочет выжать максимум, берут вместо стандартного OpenJDK дистрибутив от Eclipse Temurin или Amazon Corretto. Эти сборки считаются эталоном в сообществе серверов и не имеют известных утечек памяти.

Создание изолированного пользователя и скачивание серверного JAR файла

Запускать игровой процесс от имени root - всё равно что оставить дверь квартиры открытой и повесить табличку "заходите". Безопаснее создать отдельного системного пользователя, у которого нет ни пароля, ни интерактивной оболочки:

sudo useradd -r -m -U -d /opt/minecraft -s /bin/bash minecraft

Папка /opt/minecraft станет домом сервера. Дальше внутрь неё скачивается серверный JAR. Официальная ссылка берётся со страницы загрузки на minecraft.net, потому что адрес меняется с каждой версией. Пример команды под условную версию:

sudo -u minecraft wget -O /opt/minecraft/server.jar https://piston-data.mojang.com/v1/objects/HASH/server.jar

После первого запуска jar создаст файл eula.txt. Лицензию придётся принять честно и осознанно, поменяв false на true:

sudo -u minecraft bash -c "echo 'eula=true' > /opt/minecraft/eula.txt"

Файл server.properties формирует базовое поведение мира. Порт по умолчанию 25565, но его можно и нужно изменить, если хостинг уже слушает этот номер. Здесь же задаётся режим игры, сложность, максимальное число игроков, view-distance и spawn-protection. Многие администраторы недооценивают параметр simulation-distance, хотя именно он отвечает за радиус работы мобов и механизмов. Завышенное значение бьёт по TPS сильнее, чем кажется.

Тонкая настройка JVM через флаги Aikar для ровного TPS без провалов

Java по умолчанию не знает, что обслуживает игровой сервер. Её сборщик мусора настроен усреднённо, и при резких всплесках активности появляются те самые лаг-спайки, когда мир на половину секунды замирает. Чтобы этого избежать, в серверной среде давно прижился набор флагов, известный как Aikar Flags. Разработчик PaperMC исследовал поведение JVM неделями и собрал параметры, которые делают паузы сборщика G1GC короче и равномернее.

Типичный стартовый скрипт под 4 ГБ памяти выглядит так. Создаётся файл /opt/minecraft/start.sh следующего содержания:

#!/bin/bash
cd /opt/minecraft
exec /usr/bin/java -Xms4G -Xmx4G \
  -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 -XX:MaxTenuringThreshold=1 \
  -Daikars.new.flags=true -jar server.jar nogui

Права выдаются одной строкой: sudo chmod +x /opt/minecraft/start.sh и sudo chown minecraft:minecraft /opt/minecraft/start.sh. Важная тонкость. Значения Xms и Xmx держатся одинаковыми, это даёт JVM предсказуемое поведение кучи. На сервере с 8 ГБ оперативки под Minecraft отдают 6-6,5 ГБ, оставляя системе запас. Попытка выдать всё до последнего мегабайта заканчивается визитом OOM killer, который прибивает процесс без предупреждения.

При объёмах кучи свыше 12 ГБ разумно переключаться на чуть иные значения. G1NewSizePercent поднимается до 40, G1MaxNewSizePercent до 50, регион увеличивается до 16 МБ. Для 20 ГБ и выше G1GC уже упирается в потолок, и энтузиасты поглядывают в сторону ZGC или Shenandoah. Первый требователен к памяти, второй к процессору, оба пока не стали народным стандартом, но на мощных машинах показывают себя достойно.

Сборка юнита systemd для автозапуска после перезагрузки и падения

Запускать сервер руками через screen после каждой перезагрузки сервера - путь, на котором быстро устаёт даже терпеливый администратор. Служба systemd решает вопрос раз и навсегда. Файл создаётся по адресу /etc/systemd/system/minecraft.service.

[Unit]
Description=Minecraft Java Server
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/opt/minecraft/start.sh
Restart=on-failure
RestartSec=10
TimeoutStartSec=600
StandardInput=null

[Install]
WantedBy=multi-user.target

Ключевые детали стоит разобрать по косточкам. Wants и After гарантируют, что сервис стартует после поднятия сети. User фиксирует непривилегированного пользователя, созданного ранее. Restart=on-failure поднимает сервер только после падений, а не после штатной остановки администратором. TimeoutStartSec=600 выдаёт десять минут на старт, потому что генерация свежего мира и прогрузка мода вроде большой сборки могут занять заметно больше обычных тридцати секунд. Параметр StandardInput=null отсекает попытки внешних процессов слать ввод в консоль, и это гигиена, а не перестраховка.

Дальнейшие команды активируют службу и позволяют следить за её жизнью:

  • sudo systemctl daemon-reload - систему нужно предупредить о новом юните
  • sudo systemctl enable minecraft - сервер будет стартовать автоматически
  • sudo systemctl start minecraft - первый ручной запуск
  • sudo systemctl status minecraft - текущее состояние со статусом и PID
  • journalctl -u minecraft -f - живой поток логов, удобный для отладки

Открытие порта, проверка подключений и штрихи для безопасной работы

Пока на файрволе закрыт 25565, игроки снаружи видят чёрный экран. Стандартный ufw открывает порт одной строкой: sudo ufw allow 25565/tcp. Те, кто арендует сервер у облачного провайдера, обычно настраивают ещё и внешний сетевой фильтр в панели управления. Порт 22 для SSH разумно оставить открытым только для доверенных адресов, а лучше перевести аутентификацию на ключи и вовсе отключить вход по паролю.

Серверы Minecraft нередко становятся мишенью для небольших сетевых атак. Рядовые администраторы защищаются провайдерской фильтрацией трафика и настройкой rate limiting на уровне nftables. Ещё один важный момент - регулярные бэкапы мира. Папки world, world_nether и world_the_end достаточно упаковывать cron-скриптом раз в сутки и выкладывать на отдельное хранилище. Один случайный сбой диска, и без копии вся работа колонии жителей превращается в воспоминание.

Что в итоге выходит у того, кто прошёл этот путь. Сервер, который поднимается сам после ребута, перезапускается после падения, живёт под своим пользователем и не жрёт память сверх отведённого. Такая система выдерживает ночной наплыв игроков, чинится одним journalctl и расширяется без переустановки с нуля. И главное, весь стек прозрачен до последней строки. Если что-то идёт не так, администратор знает, в какой именно файл смотреть, а не гадает на кофейной гуще панели управления.