Когда друг в очередной раз спрашивает: «А давай поднимем свой сервер, чтобы никто не выключал?», — начинаешь гуглить и натыкаешься либо на видео сомнительного качества, либо на форумные треды десятилетней давности. А хочется, чтобы сервер работал, обновлялся, не падал и не открывал дыру в безопасности. Эта статья — практический разбор двух подходов к организации игрового сервера на Linux: «голое железо» с systemd и контейнеризация через Docker. На примере Minecraft (как самой частой истории) и Valheim (как примера из мира Steam). Без магии, с командами и конфигами.
Что нужно решить до первой команды
Прежде чем ставить пакеты, ответьте на три вопроса. От них зависит всё остальное.
Железо. Minecraft — игра, которая любит одно ядро и много памяти. Официальные требования начинаются от 1 ГБ RAM для ванильного сервера, но для 5–10 игроков уже стоит ориентироваться на 2–4 ГБ. Для модовых сборок цифры умножаются: 3 ГБ хватит на 3–8 игроков, 4 ГБ — на 8–15, а дальше — как повезёт с конкретными модами. Valheim требует минимум 4 ядра и 2 ГБ RAM, но на практике стабильнее себя чувствует с запасом.
ОС. Ubuntu 22.04/24.04 LTS или Debian 12+ — самые «обкатанные» варианты для игровых серверов. На старых дистрибутивах Valheim может не запуститься из‑за устаревшей glibc (нужна версия 2.29+). Если железо старое, Docker часто становится обходным путём, потому что тащит свои зависимости.
Подход. systemd на хосте — прозрачность и контроль. Docker — воспроизводимость и лёгкость обновлений. Ниже — оба варианта.
Вариант 1: systemd на «голом железе» (на примере Minecraft)
Этот путь хорош, когда вы хотите понимать, что происходит, и не хотите прослойки в виде контейнера.
Шаг 1. Подготовка системы и пользователя
Создаём отдельного пользователя, чтобы сервер не работал от root. Это базовое требование безопасности.
bash
sudo apt update && sudo apt upgrade -y sudo adduser minecraft
Не забудьте пароль — он понадобится для переключения. Дальше ставим Java. Для Minecraft 1.20.5+ нужна Java 21.
sudo apt install -y curl unzip openjdk-21-jdk
Шаг 2. Загрузка и первый запуск
Переключаемся на пользователя minecraft, создаём папку и качаем server.jar с официального сайта Mojang. Ссылка на конкретную версию меняется, поэтому актуальную берите на странице загрузки Java Edition.
su - minecraft mkdir -p ~/minecraft-server && cd ~/minecraft-server curl -L -o minecraft_server.jar <актуальная_ссылка_на_server.jar> echo "eula=true" > eula.txt
eula=true — это согласие с лицензией Mojang. Для тестового сервера сойдёт, но помните: вы берёте на себя ответственность за соблюдение условий.
Пробный запуск:
java -Xms2G -Xmx2G -jar minecraft_server.jar nogui
Флаги -Xms и -Xmx задают минимальный и максимальный размер heap. Для ванильного сервера на 5–10 человек 2 ГБ — разумный старт. Для модовых сборок смотрите на 4–6 ГБ и выше.
Шаг 3. systemd‑юнит: чтобы сервер пережил перезагрузку
Запускать java в screen или tmux — это не эксплуатация, это лотерея. Нормальный способ — unit‑файл. Один из распространённых шаблонов для Minecraft выглядит так:
ini
# /etc/systemd/system/minecraft@.service [Unit] Description=Minecraft Server %i After=network.target [Service] WorkingDirectory=/opt/minecraft/%i Type=simple User=minecraft Group=minecraft ProtectSystem=full ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true Environment="MCMINMEM=512M" "MCMAXMEM=1024M" ExecStart=/usr/bin/java -Xms${MCMINMEM} -Xmx${MCMAXMEM} -jar server.jar nogui Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target
Пара замечаний. ProtectSystem=full, ProtectHome=true и остальные Protect*‑директивы — это не паранойя, а нормальная практика для сетевых сервисов: они ограничивают доступ процесса к файловой системе и ядру. Шаблон @ позволяет держать несколько инстансов, если понадобится.
Активация:
sudo systemctl daemon-reload sudo systemctl enable --now minecraft@server
Логи смотрим через journalctl -u minecraft@server -f, остановку делаем через systemctl stop. Просто и предсказуемо.
Вариант 2: Docker и Docker Compose
Если не хочется вручную следить за версиями Java и обновлениями, контейнер снимает часть рутины. Для Minecraft каноническим считается образ itzg/minecraft-server: он умеет автоматически скачивать нужную версию, подтягивать модлоадеры и принимать настройки через переменные окружения.
Минимальный docker-compose.yml:
services: minecraft: image: itzg/minecraft-server tty: true stdin_open: true ports: - "25565:25565" environment: EULA: "TRUE" TYPE: "VANILLA" VERSION: "LATEST" MEMORY: "2G" volumes: - ./minecraft-data:/data restart: unless-stopped
EULA обязателен, иначе контейнер не стартует. MEMORY задаёт heap для JVM; для ванильного сервера на небольшой круг людей 2G — адекватно. Том ./minecraft-data:/data сохраняет мир и конфиги между пересозданиями контейнера — без него всё уедет в никуда.
Запуск и логи:
docker compose up -d docker logs -f <имя_контейнера>
Для Valheim логика похожая, но есть нюанс: сервер распространяется через SteamCMD, а не через прямой jar. Образ didstopia/valheim-server принимает имя сервера, мир и пароль через переменные, а также умеет автоматически проверять обновления. Пароль обязателен — без него сервер не запустится. Порты — UDP 2456-2458, это важно для файрвола.
Если хочется единого инструмента для разных игр, присмотритесь к LinuxGSM — это набор скриптов, который ставит, обновляет и бэкапит десятки выделенных серверов, включая Minecraft и Valheim. Он не отменяет понимания systemd, но снимает часть рутины с обновлениями и мониторингом.
Docker vs bare metal: что выбрать
Короткий ответ: для одного‑двух серверов «для друзей» — systemd на хосте, потому что меньше слоёв и проще диагностика. Для нескольких инстансов или если хочется легко переезжать между машинами — Docker. По производительности разница между контейнером и «голым железом» в типичных сценариях небольшая; Docker добавляет минимальный оверхед на I/O, но взамен даёт изоляцию и повторяемость. Если сервер упирается в диск или сеть, это обычно не из‑за контейнера, а из‑за железа или настроек.
Безопасность: что нельзя оставлять «на потом»
Игровой сервер — это открытый порт в интернет. Даже если там «просто майнкрафт», его найдут сканеры.
Файрвол. Открывайте только те порты, которые реально нужны. Для Minecraft это TCP 25565, для Valheim — UDP 2456-2458. Всё остальное закрыто. UFW делает это в две команды:
sudo ufw allow 25565/tcp sudo ufw allow 2456:2458/udp sudo ufw enable
Правило простое: если порт не нужен для игры или администрирования — он не должен быть доступен снаружи.
Пользователь и права. Сервер не должен работать от root. Отдельный пользователь с минимальными правами, Protect* в systemd или --read-only/--cap-drop в Docker — базовый минимум.
Сеть. Если играете только с друзьями и не хотите светить сервер в интернет, посмотрите в сторону Tailscale или WireGuard: сервер будет доступен только внутри вашей приватной сети, а публичный порт можно закрыть. Это не всегда удобно для больших сообществ, но для узкого круга — отличный вариант.
Производительность: где чаще всего «болит»
Для Minecraft главный враг — не количество ядер, а скорость одного ядра и объём памяти. Сервер использует дополнительные ядра, но основная нагрузка ложится на одно. Поэтому гнаться за 16 ядрами на дешёвом VPS смысла нет — лучше взять меньше ядер, но с высоким clock speed.
Второй рычаг — view-distance и simulation-distance в server.properties. Если сервер начинает «подтормаживать» при большом онлайне, снижение simulation-distance до 4–6 и view-distance до 6–12 даёт заметный выигрыш по TPS без катастрофической потери картинки для игроков. Сначала режьте simulation-distance: именно он влияет на тики и нагрузку, тогда как view-distance — больше про то, что видит игрок.
Для Valheim узкое место — сеть и UDP‑порты; на стороне сервера стоит убедиться, что LD_LIBRARY_PATH указывает на linux64 внутри папки сервера, иначе он может не найти библиотеки.
В заключение
Свой игровой сервер — это не «сложно», а «нужно один раз сделать аккуратно». systemd даёт контроль и понимание, Docker — скорость и воспроизводимость. В любом случае три вещи решают больше, чем остальные: отдельный пользователь, закрытый файрвол и внятный unit‑файл (или docker-compose.yml). Дальше — только обновления и бэкапы.

