Un servidor propio de Minecraft Java Edition te permite jugar con tus amigos o tu comunidad con tus propias reglas, sin depender de servicios de alojamiento de terceros. En este tutorial instalarás el servidor oficial de Mojang en Ubuntu 24.04, lo ejecutarás con un usuario sin privilegios como servicio de systemd, podrás enviarle comandos de consola, lo protegerás con una lista blanca y el firewall, y programarás copias de seguridad diarias del mundo.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Al menos 4 GB de RAM y 2 vCPUs para un grupo pequeño (hasta unos 10 jugadores). Minecraft usa sobre todo un núcleo, así que importa más la velocidad por núcleo que el número de núcleos. Para 20 jugadores o más, calcula 8 GB.
  • Una cuenta de Minecraft Java Edition para conectarte y probar el servidor.

Paso 1: Instalar Java

El servidor de Minecraft es una aplicación Java y cada versión exige una versión mínima: Minecraft 1.21 requiere Java 21. Instala las herramientas necesarias y el entorno de ejecución Java 21 sin interfaz gráfica:

sudo apt update
sudo apt install openjdk-21-jre-headless curl jq

Verifica la instalación:

java -version
openjdk version "21.0.8" 2025-07-15
OpenJDK Runtime Environment (build 21.0.8+9-Ubuntu-0ubuntu124.04.1)
OpenJDK 64-Bit Server VM (build 21.0.8+9-Ubuntu-0ubuntu124.04.1, mixed mode, sharing)

En el paso 3 comprobarás qué versión de Java pide exactamente la versión de Minecraft que descargues.

Paso 2: Crear un usuario dedicado

Ejecutar el servidor como root o con tu usuario personal es un riesgo: una vulnerabilidad en el servidor o en un plugin daría acceso a todo el sistema. Crea un usuario de sistema minecraft, sin contraseña ni shell de inicio de sesión, con su directorio en /opt/minecraft:

sudo useradd --system --create-home --home-dir /opt/minecraft --shell /usr/sbin/nologin minecraft
sudo -u minecraft mkdir -p /opt/minecraft/server /opt/minecraft/backups

Comprueba que el usuario existe:

id minecraft
uid=998(minecraft) gid=998(minecraft) groups=998(minecraft)

Paso 3: Descargar el servidor de Minecraft

Mojang publica el listado de versiones en un manifiesto JSON. En lugar de copiar a mano una URL que cambia con cada versión, consulta el manifiesto con jq para obtener la última versión estable:

MANIFEST=https://piston-meta.mojang.com/mc/game/version_manifest_v2.json
MC_VERSION=$(curl -s "$MANIFEST" | jq -r '.latest.release')
VERSION_URL=$(curl -s "$MANIFEST" | jq -r --arg v "$MC_VERSION" '.versions[] | select(.id == $v) | .url')
echo "$MC_VERSION"
1.21.8

Si prefieres una versión concreta (por ejemplo, porque tus plugins o mods aún no soportan la última), asigna MC_VERSION a mano antes de calcular VERSION_URL.

Comprueba qué versión de Java necesita:

curl -s "$VERSION_URL" | jq -r '.javaVersion.majorVersion'
21

Si el resultado es mayor que 21, instala el paquete openjdk-<versión>-jre-headless correspondiente antes de continuar (comprueba si está disponible con apt-cache search openjdk | grep jre-headless).

Obtén la URL y la suma SHA-1 del servidor, descárgalo como usuario minecraft y verifica que el archivo está íntegro:

SERVER_URL=$(curl -s "$VERSION_URL" | jq -r '.downloads.server.url')
SERVER_SHA1=$(curl -s "$VERSION_URL" | jq -r '.downloads.server.sha1')
sudo -u minecraft curl -o /opt/minecraft/server/server.jar "$SERVER_URL"
echo "$SERVER_SHA1  /opt/minecraft/server/server.jar" | sha1sum -c
/opt/minecraft/server/server.jar: OK

Paso 4: Aceptar el EULA

El servidor no arranca hasta que aceptes el EULA de Minecraft. Léelo y, si estás de acuerdo, créalo aceptado:

echo "eula=true" | sudo -u minecraft tee /opt/minecraft/server/eula.txt

Paso 5: Crear el servicio systemd

Con systemd el servidor arranca con el sistema, se reinicia si falla y guarda sus logs en el journal. El problema es la consola: Minecraft lee comandos (op, whitelist, stop) de su entrada estándar. Para poder enviárselos sin screen ni tmux, crea una unidad de tipo socket que conecta la entrada del servidor a una tubería con nombre (FIFO) en /run/minecraft.stdin.

Crea la unidad del socket:

sudo nano /etc/systemd/system/minecraft.socket
[Unit]
Description=Consola del servidor de Minecraft
PartOf=minecraft.service

[Socket]
ListenFIFO=/run/minecraft.stdin
SocketUser=minecraft
SocketGroup=minecraft
SocketMode=0660
RemoveOnStop=true

Crea la unidad del servicio:

sudo nano /etc/systemd/system/minecraft.service
[Unit]
Description=Servidor de Minecraft
Wants=network-online.target
After=network-online.target minecraft.socket
Requires=minecraft.socket

[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server
ExecStart=/usr/bin/java -Xms2G -Xmx2G -jar server.jar --nogui
Sockets=minecraft.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=10
TimeoutStopSec=90
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

Puntos clave:

  • -Xms2G -Xmx2G: memoria reservada para Java. Usa el mismo valor en ambos para evitar redimensionados, y deja al menos 1 GB libre para el sistema. En un servidor de 8 GB puedes usar -Xms6G -Xmx6G.
  • StandardInput=socket conecta la entrada del servidor a la FIFO; StandardOutput=journal es obligatorio, porque si no la salida también iría a la FIFO.
  • Al parar el servicio, systemd envía SIGTERM y el servidor guarda el mundo antes de cerrarse. TimeoutStopSec=90 le da margen para hacerlo en mundos grandes.

Carga las unidades, habilita el servicio y arráncalo:

sudo systemctl daemon-reload
sudo systemctl enable --now minecraft.service

El primer arranque genera el mundo y tarda entre 30 segundos y un par de minutos. Sigue el log hasta ver la línea Done:

sudo journalctl -u minecraft -f
[10:31:04] [Server thread/INFO]: Starting minecraft server version 1.21.8
[10:31:05] [Server thread/INFO]: Starting Minecraft server on *:25565
[10:31:42] [Server thread/INFO]: Done (35.118s)! For help, type "help"

Pulsa Ctrl+C para dejar de seguir el log (el servidor sigue en marcha).

Paso 6: Enviar comandos a la consola

Para ejecutar un comando de consola, escríbelo en la FIFO. Por ejemplo, para listar los jugadores conectados:

echo "list" | sudo tee /run/minecraft.stdin > /dev/null
sudo journalctl -u minecraft -n 1 --no-pager
[10:33:10] [Server thread/INFO]: There are 0 of a max of 20 players online:

Da permisos de operador a tu jugador para poder usar comandos dentro del juego. Sustituye your_player por tu nombre de usuario de Minecraft:

echo "op your_player" | sudo tee /run/minecraft.stdin > /dev/null

Paso 7: Configurar el servidor

El primer arranque creó /opt/minecraft/server/server.properties. Ábrelo:

sudo -u minecraft nano /opt/minecraft/server/server.properties

Ajusta estas claves (el resto puede quedarse con sus valores por defecto):

motd=Servidor de Minecraft en CubePath
max-players=20
difficulty=normal
gamemode=survival
view-distance=10
simulation-distance=8
online-mode=true
white-list=true
enforce-whitelist=true
server-port=25565
  • online-mode=true verifica cada cuenta con los servidores de Mojang. No lo desactives: permitiría a cualquiera entrar con el nombre de otro jugador, incluido un operador.
  • white-list y enforce-whitelist solo dejan entrar a los jugadores de la lista blanca y expulsan a los que se retiren de ella.
  • view-distance y simulation-distance son los ajustes que más afectan al rendimiento. Si el servidor va lento con muchos jugadores, bájalos a 8 y 6.

Reinicia el servidor para aplicar los cambios y añade a la lista blanca a tu jugador y a los de tus amigos:

sudo systemctl restart minecraft
echo "whitelist add your_player" | sudo tee /run/minecraft.stdin > /dev/null

Comprueba la lista:

echo "whitelist list" | sudo tee /run/minecraft.stdin > /dev/null
sudo journalctl -u minecraft -n 1 --no-pager
[10:40:22] [Server thread/INFO]: There are 1 whitelisted player(s): your_player

Paso 8: Abrir el puerto en el firewall

Minecraft Java Edition usa el puerto TCP 25565. Si usas UFW, permite SSH antes de activarlo para no perder el acceso, y después abre el puerto del juego:

sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw enable
sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
25565/tcp                  ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
25565/tcp (v6)             ALLOW       Anywhere (v6)

Comprueba que Java escucha en el puerto:

sudo ss -tlnp | grep 25565
LISTEN 0      4096               *:25565            *:*    users:(("java",pid=2931,fd=40))

Ahora abre Minecraft Java Edition, ve a Multijugador > Añadir servidor e introduce your_server_ip como dirección. Si usas un puerto distinto de 25565, añádelo con dos puntos (your_server_ip:25566). Si tienes un dominio, crea un registro A apuntando a la IP del servidor y úsalo en su lugar.

Paso 9: Programar copias de seguridad del mundo

Copiar la carpeta del mundo mientras el servidor escribe en ella puede producir copias corruptas. El procedimiento correcto es desactivar el guardado automático, forzar un guardado completo, copiar y volver a activarlo. Crea el script:

sudo nano /usr/local/bin/minecraft-backup
#!/usr/bin/env bash
set -euo pipefail

SERVER_DIR=/opt/minecraft/server
BACKUP_DIR=/opt/minecraft/backups
CONSOLE=/run/minecraft.stdin
KEEP_DAYS=7
STAMP=$(date +%F-%H%M)

send() {
  echo "$1" > "$CONSOLE"
}

if systemctl is-active --quiet minecraft; then
  send "save-off"
  trap 'send "save-on"' EXIT
  send "save-all flush"
  sleep 15
fi

tar -czf "$BACKUP_DIR/world-$STAMP.tar.gz" -C "$SERVER_DIR" world
find "$BACKUP_DIR" -name 'world-*.tar.gz' -mtime +"$KEEP_DAYS" -delete

El trap garantiza que el guardado automático se reactiva aunque tar falle. Hazlo ejecutable y pruébalo como usuario minecraft:

sudo chmod 755 /usr/local/bin/minecraft-backup
sudo -u minecraft /usr/local/bin/minecraft-backup
ls -lh /opt/minecraft/backups
-rw-r--r-- 1 minecraft minecraft 48M Sep 25 10:52 world-2026-09-25-1052.tar.gz

Prográmalo a diario a las 04:30 en el crontab del usuario minecraft:

sudo crontab -u minecraft -e
30 4 * * * /usr/local/bin/minecraft-backup

Guarda también copias fuera del servidor (por ejemplo, con rsync a otra máquina o en almacenamiento de objetos): una copia en el mismo disco no te protege si el disco falla.

Para restaurar una copia, detén el servidor, sustituye la carpeta world y vuelve a arrancarlo:

sudo systemctl stop minecraft
sudo -u minecraft mv /opt/minecraft/server/world /opt/minecraft/server/world.old
sudo -u minecraft tar -xzf /opt/minecraft/backups/world-2026-09-25-1052.tar.gz -C /opt/minecraft/server
sudo systemctl start minecraft

Actualizar a una nueva versión de Minecraft

Haz una copia del mundo, repite el paso 3 para descargar el nuevo server.jar (comprueba la versión de Java que pide) y reinicia el servicio:

sudo -u minecraft /usr/local/bin/minecraft-backup
sudo systemctl restart minecraft

El mundo se convierte automáticamente al nuevo formato en el primer arranque. Este cambio no tiene vuelta atrás, por eso la copia previa es imprescindible.

Solución de problemas

UnsupportedClassVersionError en el log: la versión de Java instalada es más antigua que la que exige el servidor. Consulta javaVersion.majorVersion como en el paso 3 e instala la versión correspondiente.

El servidor se reinicia en bucle o aparece OutOfMemoryError: -Xmx es insuficiente para el mundo y los jugadores, o supera la RAM disponible. Revisa free -h y ajusta -Xms/-Xmx en /etc/systemd/system/minecraft.service, seguido de sudo systemctl daemon-reload y sudo systemctl restart minecraft.

Los jugadores ven You are not white-listed on this server!: añade su nombre con whitelist add, escrito exactamente como aparece en su cuenta de Minecraft.

No se puede conectar desde fuera (Connection timed out): comprueba con sudo ss -tlnp | grep 25565 que el servidor escucha y con sudo ufw status que el puerto está abierto.

Conclusión

Tienes un servidor de Minecraft Java Edition funcionando como servicio systemd con un usuario sin privilegios, consola accesible, lista blanca, firewall y copias diarias del mundo. Como siguientes pasos, puedes sustituir el servidor oficial por Paper, un servidor compatible con mejor rendimiento y soporte para plugins, añadir un registro SRV en tu DNS para usar un dominio sin especificar el puerto, o enviar las copias de seguridad a otro servidor con rsync desde el mismo cron.