docker-compose.yml, demostrar que el mundo sobrevive a borrar contenedores, y abrirlo para que jueguen contigo los compañeros que estén en tu misma red. Es el mismo tipo de proyecto que la práctica 34 (un servicio autoalojado), pero aplicado a algo que mueve a casi todo el mundo: un servidor de juego. Y al hacerla aprendes los mismos conceptos profesionales: stack de contenedores, persistencia de datos, publicación de puertos, administración por consola y diagnóstico de fallos. Al final, un Anexo opcional te enseña a abrirlo también a internet con un túnel.
docker run hello-world; si no responde, vuelve a la 33. Sobre el cliente de Minecraft: el servidor lo monta cualquiera, pero para conectarte y comprobar que funciona necesitas el cliente de Minecraft Java Edition, que es de pago. Si no lo tienes, haz la práctica en pareja con alguien que sí: tú montas el servidor, esa persona se conecta, y os turnáis. Todo lo demás (Docker, la consola del servidor) es gratuito.
Objetivos de la práctica
- Entender qué hace un servidor de Minecraft y por qué containerizarlo resuelve los problemas típicos de versión de Java, configuración y portabilidad.
- Levantar el servidor con un único
docker-compose.ymlusando la imagenitzg/minecraft-server, la estándar de facto. - Comprender el papel del fichero
eula.txty la variableEULA: el primer "fallo" con el que te vas a topar. - Demostrar que el mundo persiste en un volumen Docker y que sobrevive a recrear el contenedor; hacer y restaurar un backup correcto (con flush previo del mundo).
- Entender la publicación de puertos de Docker y cómo gracias a ella el servidor es accesible desde otros equipos de la red local sin tocar nada.
- Averiguar la IP de tu equipo en la red y conseguir que se conecten compañeros de tu misma red.
- Diagnosticar los problemas típicos que impiden la conexión en red local: firewall de Windows y aislamiento de clientes.
- Administrar el servidor en caliente con su consola RCON: operadores, lista blanca, dificultad, mensajes, expulsiones.
- Conocer la diferencia entre servidor VANILLA y PAPER, y cuándo merece la pena cada uno.
- Provocar y diagnosticar cinco fallos típicos: EULA sin aceptar, memoria insuficiente, desajuste de versiones cliente/servidor, volumen del mundo borrado, puerto publicado cambiado.
- Endurecer el servidor: lista blanca, operadores mínimos,
online-mode, contraseña de RCON y backups. - OPCIONAL Abrir el servidor a internet con un túnel TCP para que jueguen personas de fuera de tu red.
- Documentar el despliegue en una ficha técnica reutilizable.
Parte 0 - Conceptos previos (45 min)
0.1 - Qué es un servidor de Minecraft
Minecraft tiene dos piezas: el cliente (el juego que abres y con el que ves el mundo) y el servidor (un programa sin gráficos que mantiene el mundo, calcula la física, guarda los bloques y sincroniza a todos los jugadores conectados). Cuando juegas tú solo, el propio cliente lleva un mini-servidor dentro. Cuando quieres jugar varias personas a la vez en el mismo mundo, hace falta un servidor de verdad, encendido, al que todos se conectan.
El servidor oficial es un programa Java (un .jar). Para que funcione necesita: la versión correcta de Java (cada versión de Minecraft pide una concreta), suficiente memoria RAM asignada, un fichero de configuración (server.properties), y una carpeta donde guarda el mundo y los datos. Montarlo "a mano" significa instalar y mantener todo eso tú.
0.2 - Por qué montarlo con Docker
| Problema clásico montándolo a mano | Cómo lo resuelve Docker |
|---|---|
| "Tengo Java pero es la versión que no es" | La imagen trae la versión de Java exacta que pide el servidor |
| "Quiero probar otra versión de Minecraft sin romper la actual" | Cambias una variable VERSION y levantas otro contenedor aparte |
| "Se me han mezclado los mundos y la configuración por todo el disco" | Todo vive en un volumen con nombre, ordenado |
| "Funciona en mi PC pero no sé replicarlo en otro" | El mismo docker-compose.yml levanta lo mismo en cualquier equipo |
| "Lo cierro mal y se corrompe el mundo" | El contenedor para el servidor de forma ordenada y hay consola para hacer save antes |
No es magia: Docker no hace que el servidor consuma menos RAM ni vaya más rápido. Lo que hace es encapsular el lío de dependencias y configuración para que montarlo, moverlo y reproducirlo deje de ser un problema.
0.3 - Arquitectura de esta práctica
El cuerpo de la práctica usa un único contenedor: el servicio mc, con la imagen itzg/minecraft-server, que es el servidor de Minecraft con su Java, su configuración y el mundo. Nada más. En el Anexo opcional del final se añade un segundo contenedor para abrir el servidor también a internet, pero para jugar con tu clase en la misma red no hace falta.
itzg/minecraft-server: es un proyecto de la comunidad, mantenido desde hace años, que se ha convertido en el estándar de facto para correr Minecraft en Docker. Se configura entero por variables de entorno (versión, memoria, dificultad, operadores...) y trae herramientas dentro, como la consola RCON, que vas a usar en la Parte 4.
0.4 - Red local frente a internet
Hay dos escenarios muy distintos para "abrir" un servidor, y entender la diferencia es clave:
| Red local (LAN) | Internet | |
|---|---|---|
| Quién se conecta | Equipos de tu misma red: el aula, tu casa | Cualquiera, desde cualquier sitio |
| Cómo se conectan | Directamente, a la IP privada de tu equipo | Hace falta un túnel o abrir puertos del router |
| Configuración necesaria | Casi ninguna: Docker ya publica el puerto | Cuenta en un servicio de túnel, o tocar el router |
| Esta práctica | El cuerpo principal | El Anexo opcional del final |
Cuando dos equipos están en la misma red local, se ven directamente: uno puede hablar con el otro usando su IP privada (las que empiezan por 192.168. o 10.). No hay router de por medio bloqueando nada, porque el tráfico no sale de la red. Por eso, para jugar con tu clase, no necesitas túneles ni configurar el router: basta con que Docker publique el puerto del servidor y que tus compañeros conozcan tu IP.
El problema aparece cuando quieres que entre alguien de fuera de tu red: ahí sí hay un router que no deja pasar conexiones entrantes, y se necesita un túnel. Eso es lo que resuelve el Anexo, y es el mismo concepto que usaste en la práctica 34 con Nextcloud.
0.5 - online-mode y cuentas premium
El servidor tiene un ajuste, online-mode, que por defecto está en true. Significa que verifica con los servidores de Mojang/Microsoft que cada jugador que entra tiene una cuenta legítima de Minecraft. Es lo correcto y lo que vas a dejar puesto: garantiza que cada jugador es quien dice ser y protege el servidor. La consecuencia es que sólo podrán conectarse personas con el juego de pago. No vamos a desactivarlo: un servidor con online-mode=false es un coladero y además incumple las condiciones del juego.
0.6 - Metodología de la práctica
Mismo orden que las prácticas 33 y 34:
- Levantar el servidor y verificar que arranca (Parte 1).
- Demostrar que el mundo persiste y aprender a hacer backup (Parte 2).
- Conseguir que se conecten compañeros de tu red local (Parte 3).
- Administrar el servidor por consola RCON (Parte 4).
- Romper a propósito y diagnosticar (Parte 5).
- Endurecer el servidor (Parte 6).
- Documentar (Parte 7).
- OPCIONAL Abrir el servidor a internet con un túnel (Anexo).
Parte 1 - Levantar el servidor con Compose (50 min)
Primero vas a montar el servidor y comprobar que funciona conectándote desde tu propio Windows. Cuando esté firme, en la Parte 3 lo abrirás al resto de la red.
1.1 - Crear la carpeta de trabajo
- En el Explorador de Windows, crea una carpeta
C:\docker\minecraft. - Dentro crearás un único archivo,
docker-compose.yml. El mundo no irá aquí: Docker lo mete en un volumen propio para que sobreviva a borrar el contenedor.
1.2 - El docker-compose.yml
Crea C:\docker\minecraft\docker-compose.yml con este contenido. Usa Visual Studio Code o cualquier editor; si usas el Bloc de notas, al guardar elige "Todos los archivos" en el tipo para que no le añada .txt.
services:
mc:
image: itzg/minecraft-server:latest
restart: unless-stopped
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: VANILLA
VERSION: LATEST
MEMORY: 2G
MOTD: "Servidor del curso - Practica 35"
DIFFICULTY: normal
MAX_PLAYERS: 10
volumes:
- mc_data:/data
volumes:
mc_data:
Lee el archivo entero antes de seguir. Los puntos clave:
- Un solo servicio,
mc. Es todo lo que necesitas para jugar en red local. EULA: "TRUE"es tu aceptación del acuerdo de licencia de Minecraft. Sin esto el servidor no arranca: es de hecho el primer fallo que provocarás en la Parte 5. Déjalo en TRUE para que arranque ahora.TYPE: VANILLAes el servidor oficial sin modificar. En la Parte 4 verásPAPER, una variante optimizada que admite plugins.VERSION: LATESTcoge la última versión estable. En el Caso C de la Parte 5 lo fijarás a una versión concreta a propósito.MEMORY: 2Ges la RAM que se asigna al servidor. Demasiado poca y se cae (Caso B); demasiada y ahogas tu Windows.ports: "25565:25565"publica el puerto del servidor: lo saca del contenedor y lo expone en tu Windows. Esta línea es la que, en la Parte 3, hará que el servidor sea accesible desde otros equipos de la red. El número de la izquierda es el puerto en tu Windows; el de la derecha, el de dentro del contenedor.- Un volumen con nombre,
mc_data, montado en/data: ahí dentro vive el mundo, la configuración y los registros. Sobrevive a uncompose down.
1.3 - Primer arranque
Abre PowerShell, sitúate en la carpeta y arranca:
cd C:\docker\minecraft docker compose up -d docker compose ps
El primer up tarda un rato: descarga la imagen y, sobre todo, genera el mundo la primera vez (esto puede llevar uno o dos minutos). Mira los logs en directo en otra ventana de PowerShell:
docker compose logs -f mc
Verás líneas de descarga del servidor, de generación del mundo ("Preparing spawn area" subiendo de 0% a 100%) y finalmente la línea que indica que está listo:
mc-1 | [Server thread/INFO]: Done (12.345s)! For help, type "help"
Cuando aparezca "Done", el servidor está operativo. Ctrl+C cierra el seguimiento de logs (no para el contenedor). Comprueba también el estado:
docker compose ps
La imagen itzg/minecraft-server trae una comprobación de salud incorporada, así que cuando el servidor esté del todo arrancado, docker compose ps mostrará el contenedor como Up X minutes (healthy). Si todavía pone (starting) o (health: starting), dale unos segundos más.
| Tiempo aproximado del primer arranque (hasta "Done") | |
STATUS del contenedor en docker compose ps | |
| Versión de Minecraft que indican los logs |
1.4 - Conectarte desde tu cliente
- Abre el cliente de Minecraft Java Edition. Asegúrate de que la versión del cliente coincide con la del servidor que viste en los logs (si el servidor es LATEST, usa el perfil de la última versión).
- Multijugador → Añadir servidor.
- En "Dirección del servidor" pon
localhost(o127.0.0.1). - Guarda, selecciónalo y entra.
Estás dentro de tu propio servidor. Verás el mensaje del día (MOTD) que pusiste en el compose. Date una vuelta: rompe algún bloque, construye algo pequeño. Eso ya es estado del mundo que tiene que persistir.
¿Cargó el mundo al conectarte por localhost? | |
| ¿Qué construiste o rompiste como "marca" para comprobar la persistencia luego? |
1.5 - La consola del servidor (RCON)
Un servidor de Minecraft se administra por consola: una línea de comandos donde escribes órdenes como list (ver quién está conectado), say (mandar un mensaje a todos), op (dar permisos de administrador). La imagen trae una herramienta, rcon-cli, que te abre esa consola desde dentro del contenedor. Pruébala:
docker compose exec mc rcon-cli
Se abre un prompt. Escribe list y pulsa Enter: te dice cuántos jugadores hay conectados y quiénes. Escribe say Hola desde la consola y, si estás conectado con el cliente, verás el mensaje aparecer en el chat del juego. Para salir de la consola escribe exit o pulsa Ctrl+C.
También puedes lanzar un único comando sin abrir la consola interactiva:
docker compose exec mc rcon-cli list
¿Cuántos jugadores reportó list? | |
¿Apareció el say en el chat del juego? |
Acabas de levantar un servidor de Minecraft con la versión correcta de Java sin instalar Java en tu Windows. Piensa en cuántas cosas distintas tendrías que haber descargado, instalado y configurado para conseguir lo mismo a mano. ¿Por qué esa diferencia es la razón por la que se usa Docker para esto?
Parte 2 - Persistencia y backup del mundo (30 min)
Antes de abrir el servidor a nadie, demuéstrate que el mundo sobrevive a borrar contenedores. Si esto falla, lo descubres ahora; no cuando lleves semanas de construcciones.
2.1 - Inspeccionar el volumen
docker volume ls | findstr minecraft docker volume inspect minecraft_mc_data
El prefijo minecraft_ lo añade Compose porque así se llama la carpeta. Anota la ruta del campo Mountpoint: ahí, dentro de WSL2, vive tu mundo.
Mountpoint del volumen mc_data |
2.2 - El experimento "borro y recreo"
- Asegúrate de tener tu "marca" del paso 1.4 hecha en el mundo (un bloque roto, una construcción). Si no tienes cliente, salta este experimento o pídele a tu pareja que deje una marca en la Parte 3.
- Para los contenedores conservando el volumen:
docker compose down
Para y elimina el contenedor y la red. El volumen no se toca. - Comprueba:
docker volume ls | findstr minecraft— ahí sigue. - Vuelve a levantar:
docker compose up -d
Esta vez es rápido: no descarga la imagen ni regenera el mundo. - Conéctate de nuevo: tu marca sigue ahí. El mundo es el mismo.
2.3 - Lo que NO hay que hacer
docker compose down -v
El flag -v elimina también el volumen. Es la forma de empezar de cero, pero borra el mundo entero sin preguntar. Memoriza la diferencia: down sin flag conserva el mundo; down -v lo pulveriza. Este es exactamente el Caso D de la Parte 5.
2.4 - Backup correcto del mundo
Aquí hay un detalle importante: el servidor mantiene parte del mundo en memoria y lo va guardando a disco poco a poco. Si copias el volumen mientras el servidor está escribiendo, puedes copiar un mundo a medio guardar. La forma correcta es pedirle al servidor que vuelque todo a disco y pause el guardado mientras copias.
# 1. Forzar el guardado del mundo y pausar nuevas escrituras
docker compose exec mc rcon-cli save-off
docker compose exec mc rcon-cli save-all
# 2. Copiar el volumen del mundo a un .tgz dentro del host
docker run --rm -v minecraft_mc_data:/data -v ${PWD}:/backup alpine `
tar czf /backup/backup_mundo.tgz -C /data .
# 3. Reactivar el guardado automático
docker compose exec mc rcon-cli save-on
El comando del medio es el patrón canónico: un contenedor Alpine efímero con el volumen montado en /data y la carpeta actual de Windows en /backup, que comprime todo en un .tgz. La novedad frente a la práctica 34 es el save-off / save-all / save-on alrededor: sin eso, el backup puede salir inconsistente.
save-off puesto y no haces save-on después, el servidor deja de guardar el mundo: todo lo que construyan los jugadores se perderá al parar el contenedor. El save-on del paso 3 no es opcional.
Tamaño de backup_mundo.tgz | |
¿Ejecutaste el save-on final? |
Parte 3 - Jugar en red local con tus compañeros (45 min)
Hasta aquí tienes un servidor que sólo tú ves desde tu propio Windows. Ahora vas a comprobar que cualquiera de tu misma red puede entrar, sin tocar el router ni configurar absolutamente nada más.
3.1 - Por qué ya está casi hecho
Recuerda la línea ports: "25565:25565" del compose. Eso publica el puerto del servidor en tu Windows en todas las interfaces de red, no sólo en localhost. Es decir: tu equipo ya está escuchando peticiones de Minecraft en el puerto 25565, vengan de donde vengan dentro de tu red. No hay que añadir nada al compose. Lo único que falta es que tus compañeros sepan a qué dirección apuntar.
3.2 - Averiguar tu IP en la red
Tus compañeros no se conectan a localhost (eso es "este mismo equipo" para cada uno). Se conectan a la IP de tu equipo dentro de la red. Averíguala:
ipconfig
Busca el adaptador que estés usando de verdad —Adaptador de LAN inalámbrica Wi-Fi si vas por wifi, Adaptador de Ethernet si vas por cable— y apunta el campo Dirección IPv4. Será algo como 192.168.1.45 o 10.0.0.23.
172. que verás en adaptadores llamados vEthernet o WSL: esas son las redes internas de Docker y WSL, no la de tu aula. La buena es la del adaptador Wi-Fi o Ethernet real, normalmente 192.168.x.x.
| Adaptador que usas (Wi-Fi / Ethernet) | |
| Tu Dirección IPv4 en la red |
3.3 - Que se conecte alguien de tu red
- Dale a un compañero de tu misma red tu IP y el puerto. La dirección que tiene que poner en su Minecraft es
TU_IP:25565, por ejemplo192.168.1.45:25565. - Esa persona abre Minecraft, Multijugador → Añadir servidor, y pega esa dirección.
- Entra. Si todo está bien, ve tu mundo y tu MOTD.
- Compruébalo tú con la consola:
docker compose exec mc rcon-cli listdebe mostrar a ese jugador conectado.
Acabas de tener a alguien jugando en un servidor que corre en tu portátil, sin haber instalado nada en su equipo más que el propio Minecraft y sin haber tocado la red. Eso es exactamente lo que hace un servidor profesional: publica un puerto y la gente se conecta a él.
| ¿Quién se conectó y desde qué equipo? | |
¿Apareció en rcon-cli list? | |
| Latencia (ping) que veía ese jugador |
3.4 - Si no se conectan: los dos sospechosos habituales
Si tú entras por localhost pero tu compañero no entra por tu IP, el servidor está bien: el problema está en la red o en el firewall. Hay dos causas que cubren casi todos los casos.
Sospechoso 1: el Firewall de Windows
El Firewall de Windows puede estar bloqueando las conexiones entrantes al puerto 25565. Docker Desktop a veces añade la regla solo, pero no siempre. Para crear la regla a mano:
- Abre Firewall de Windows Defender con seguridad avanzada (búscalo en el menú Inicio).
- Reglas de entrada → Nueva regla.
- Tipo Puerto → TCP → puerto específico 25565.
- Permitir la conexión. Aplícala al perfil de red que uses (normalmente Privada; en el aula podría ser Pública, pregunta si dudas).
- Ponle un nombre reconocible, por ejemplo Minecraft servidor 25565.
Sospechoso 2: aislamiento de clientes en la red
Algunas redes de centros, oficinas y wifis públicas tienen aislamiento de clientes ("client isolation" / "AP isolation"): los equipos tienen internet pero no se ven entre sí. Si es eso, no hay nada que tocar en tu equipo: es la configuración de la red, y la red local no funcionará por mucho que ajustes el firewall.
Se comprueba en 10 segundos: que tu compañero te haga un ping a tu IP.
ping 192.168.1.45
(con tu IP real). Si el ping responde, los equipos se ven y el problema es el firewall. Si el ping no responde pero ambos tenéis internet, es aislamiento de clientes: la red no deja. En ese caso, para hacer la prueba multijugador necesitaríais una red sin aislamiento (un punto de acceso propio, compartir datos del móvil entre los dos equipos, etc.) o usar el Anexo para salir por internet.
| ¿Tuviste que crear la regla de firewall? | |
¿Respondió el ping entre los dos equipos? | |
| Diagnóstico final si no conectaba (firewall / aislamiento / IP mal / otro) |
Explica con tus palabras por qué tus compañeros se conectan a tu IP 192.168.x.x y no a localhost. ¿Por qué en una red local no hace falta tocar el router, y sí haría falta si quisieras que entrara alguien desde su casa?
Parte 4 - Administrar el servidor por consola (40 min)
Un servidor con gente conectada hay que administrarlo: dar permisos a quien debe tenerlos, controlar quién entra, ajustar las reglas del juego. Todo eso se hace por la consola RCON que probaste en la Parte 1.5.
4.1 - Comandos básicos de administración
Abre la consola con docker compose exec mc rcon-cli y prueba estos comandos (dentro de la consola se escriben sin docker compose... delante):
| Comando | Qué hace |
|---|---|
list | Lista los jugadores conectados |
say <mensaje> | Manda un mensaje a todo el servidor |
op <jugador> | Da permisos de operador (administrador) a un jugador |
deop <jugador> | Quita los permisos de operador |
kick <jugador> | Expulsa a un jugador (puede volver a entrar) |
ban <jugador> | Banea a un jugador (no puede volver a entrar) |
difficulty <peaceful|easy|normal|hard> | Cambia la dificultad en caliente |
weather clear | Despeja el clima |
stop | Para el servidor de forma ordenada (el contenedor se reiniciará por restart: unless-stopped) |
4.2 - Hacerte operador
Por defecto nadie es operador. Para administrar el juego desde dentro (volar, cambiar de modo, dar objetos) date permisos a tu propio usuario de Minecraft:
docker compose exec mc rcon-cli op TuNombreDeMinecraft
A partir de ahí, dentro del juego, tienes acceso a los comandos de operador (la tecla de chat, y comandos como /gamemode creative).
OPS: TuNombreDeMinecraft al bloque environment del servicio mc, ese jugador será operador automáticamente cada vez que se cree el contenedor. Útil para no depender de acordarte de hacer op a mano.
4.3 - Lista blanca: que sólo entre quien tú quieras
En la red del aula, cualquiera que averigüe tu IP puede intentar entrar a tu servidor. La lista blanca (whitelist) le da la vuelta: sólo entran los jugadores que tú añadas explícitamente.
docker compose exec mc rcon-cli whitelist on docker compose exec mc rcon-cli whitelist add TuNombreDeMinecraft docker compose exec mc rcon-cli whitelist add NombreDeTuCompañero docker compose exec mc rcon-cli whitelist list
Desde que activas la lista blanca, quien no esté en ella recibe un "no estás en la lista blanca de este servidor" al intentar conectarse. Pruébalo: pide a alguien que no hayas añadido que intente entrar, y luego añádelo y que vuelva a probar.
| ¿A quién rechazó la lista blanca antes de añadirlo? | |
¿Entró bien después de un whitelist add? |
4.4 - VANILLA vs PAPER
El TYPE: VANILLA de tu compose es el servidor oficial tal cual. Hay una alternativa muy usada, PAPER, que es el servidor oficial reescrito por la comunidad para ir más rápido y, sobre todo, para admitir plugins (mini-extensiones: protección de zonas, economía, mini-juegos, anti-trampas...).
| VANILLA | PAPER | |
|---|---|---|
| Comportamiento | El juego "puro", idéntico al modo un jugador | Idéntico de cara al jugador, optimizado por dentro |
| Plugins | No admite | Sí, miles disponibles |
| Rendimiento con muchos jugadores | Correcto | Claramente mejor |
| Cuándo elegirlo | Quieres la experiencia oficial sin añadidos | Quieres plugins o vas a tener bastante gente |
Cambiar de uno a otro con esta imagen es trivial: basta con poner TYPE: PAPER en el compose y volver a hacer docker compose up -d. No lo hagas todavía si tienes un mundo que te importa sin backup; aunque el mundo es compatible, es buena costumbre respaldar antes de cualquier cambio de tipo de servidor.
TYPE: PAPER, levanta de nuevo y comprueba en los logs que ahora arranca Paper. Si te animas, busca un plugin sencillo, colócalo en la carpeta plugins del volumen /data y reinicia para verlo cargar.
Parte 5 - Provocar y diagnosticar tus propios fallos (90 min)
Como en las prácticas anteriores, vas a romper a propósito cinco cosas, hacer como si te las acabases de encontrar y diagnosticarlas. Son los fallos típicos de un servidor de Minecraft containerizado.
5.1 - Caso A - El servidor no arranca: EULA sin aceptar
Qué rompes: en el compose, cambia EULA: "TRUE" por EULA: "FALSE" y recrea:
docker compose up -d docker compose ps
El contenedor mc aparecerá como Exited o reiniciándose en bucle. El servidor no levanta.
Diagnostica:
- Síntoma: "el servidor no arranca, el contenedor se cierra solo".
docker compose ps:mcestá Exited o Restarting.docker compose logs --tail 20 mc: aparece el mensaje claro "You need to agree to the EULA in order to run the server".- Causa: el servidor de Minecraft exige que aceptes su acuerdo de licencia, y la imagen traslada esa aceptación a la variable
EULA.
Repara: vuelve a poner EULA: "TRUE" y docker compose up -d. El servidor arranca.
| Mensaje exacto que mostraron los logs | |
Estado del contenedor con EULA: "FALSE" |
5.2 - Caso B - El servidor se cae: memoria insuficiente
Qué rompes: en el compose, baja MEMORY: 2G a MEMORY: 256M (muy poca RAM para un Minecraft moderno) y recrea:
docker compose up -d docker compose logs -f mc
Con tan poca memoria, el servidor casca durante la generación del mundo con un error de memoria de Java. Si por lo que sea sobrevive al arranque y llega a "Done", conéctate con el cliente y muévete por el mundo (eso obliga a generar terreno nuevo y consume memoria): el error aparecerá enseguida.
Diagnostica:
- Síntoma: "el servidor arranca pero se cae solo a los pocos segundos / no llega a 'Done'".
docker compose logs --tail 40 mc: busca líneas conjava.lang.OutOfMemoryErroroGC overhead limit.docker compose ps: el contenedor está en bucle de reinicio (Restarting) por la políticarestart: unless-stopped.- Causa: a Java se le ha asignado tan poca RAM que no puede sostener ni la generación del mundo.
Repara: vuelve a MEMORY: 2G (o más si tu equipo lo permite) y docker compose up -d. Espera a la línea "Done" para confirmar que ya no casca.
MEMORY: 12G en un portátil con 8 GB de RAM. Ahí el problema no es Minecraft, es que ahogas a Windows entero. La RAM asignada al servidor tiene que dejar margen de sobra para el sistema y para Docker Desktop.
| Línea de error más reveladora de los logs | |
¿Con cuánta MEMORY volvió a arrancar bien? |
5.3 - Caso C - Nadie puede entrar: desajuste de versiones
Qué rompes: en el compose, fija VERSION a una versión concreta que no sea la de tu cliente. Por ejemplo, si tu cliente está en la última, pon VERSION: "1.20.4":
docker compose up -d docker compose logs --tail 10 mc
El servidor arranca perfectamente. Pero al intentar conectarte desde el cliente, te rechaza.
Diagnostica:
- Síntoma: "el servidor está Up y (healthy), pero el cliente no entra".
- El mensaje en el cliente es muy explícito: algo del tipo "Outdated client" o "Outdated server", indicando la versión que espera cada lado.
docker compose logs --tail 10 mc: confirma con qué versión arrancó el servidor.- Causa: el protocolo de Minecraft cambia entre versiones; cliente y servidor tienen que hablar la misma.
Repara: tienes dos caminos, y entender la diferencia es lo importante:
- Cambiar el servidor a la versión del cliente (vuelve a
VERSION: LATESTo pon la versión exacta de tu cliente). - O cambiar el cliente: en el lanzador de Minecraft puedes crear un perfil con la versión
1.20.4y conectarte con ese.
| Mensaje exacto que mostró el cliente | |
| ¿Resolviste cambiando el servidor o el cliente? |
5.4 - Caso D - El mundo desaparecido: volumen borrado
Qué rompes: el horror clásico. Alguien hace down -v "para reiniciar limpio" y se lleva por delante el volumen del mundo. Vas a recuperarlo del backup de la Parte 2.4.
backup_mundo.tgz en C:\docker\minecraft antes de seguir. Si no lo tienes, vuelve a la Parte 2.4 y créalo. Sin backup, este caso te deja a cero de verdad.
- Para todo y borra el volumen:
docker compose down -v
- Confirma el desastre:
docker volume ls | findstr minecraftya no muestra nada. - Levanta de nuevo:
docker compose up -d. Como el volumen se crea vacío, el servidor genera un mundo nuevo desde cero: tus construcciones no están.
Diagnostica: el síntoma es inconfundible ("ayer tenía mi mundo y hoy aparezco en un mundo nuevo"), y la causa, comparando con tu apunte del Mountpoint de la Parte 2.1, es que el volumen es uno nuevo: el anterior se borró.
Repara restaurando el backup:
# 1. Parar el servidor para que no escriba mientras restauras
docker compose stop mc
# 2. Volcar el contenido del backup en el volumen (que up -d ya recreó vacío)
docker run --rm -v minecraft_mc_data:/data -v ${PWD}:/backup alpine `
sh -c "cd /data && tar xzf /backup/backup_mundo.tgz"
# 3. Arrancar de nuevo
docker compose start mc
Conéctate: tu mundo, con tus construcciones, ha vuelto.
¿Qué viste al entrar tras el down -v (antes de restaurar)? | |
| ¿Recuperaste tus construcciones con el backup? |
5.5 - Caso E - Nadie encuentra el servidor: el puerto publicado cambiado
Qué rompes: en el compose, cambia el puerto publicado de "25565:25565" a "25566:25565" y recrea:
docker compose up -d docker compose ps
El servidor sigue Up y (healthy). Pero ni tú por localhost:25565 ni tus compañeros por TU_IP:25565 conseguís entrar: la dirección de siempre ya no responde.
Diagnostica:
- Síntoma: "el servidor está perfecto en
docker compose pspero nadie se conecta a la dirección de siempre". docker compose ps: fíjate en la columna PORTS. Ahora pone0.0.0.0:25566->25565/tcp: el puerto de fuera ya no es el 25565. Pista clave.- Como el contenedor está sano y el cambio es de mapeo de puertos, el problema está en la publicación, no en el servidor.
- Causa: alguien tocó el lado izquierdo del
ports. El servidor sigue escuchando en su 25565 interno, pero hacia fuera se publica en otro puerto.
Repara: tienes dos caminos válidos, y verlos los dos enseña cómo funciona el mapeo de puertos:
- Volver el compose a
"25565:25565"ydocker compose up -d: la dirección de siempre vuelve a funcionar. - O dejarlo en 25566 y avisar a todos de que ahora la dirección es
TU_IP:25566. Funciona igual, pero todo el mundo tiene que actualizar la dirección guardada. Esto te enseña por qué el puerto publicado no se cambia "porque sí" una vez que hay gente conectándose.
| Qué ponía la columna PORTS con el puerto cambiado | |
| ¿Resolviste volviendo a 25565 o avisando del nuevo puerto? |
5.6 - Tabla resumen de los cinco casos
| Caso | Tiempo total (min) | Comando que dio la pista clave | ¿Lo resolverías hoy en 5 minutos? |
|---|---|---|---|
| A - EULA sin aceptar | |||
| B - Memoria insuficiente | |||
| C - Desajuste de versiones | |||
| D - Volumen borrado | |||
| E - Puerto publicado cambiado |
MEMORYY en lugar de MEMORY) y observa qué pasa al levantar y qué dicen los logs. Documenta el síntoma, el comando que lo confirma y la solución, con el mismo formato que los cinco casos anteriores.
Parte 6 - Endurecer el servidor (30 min)
Lo que tienes funciona, pero un servidor con gente conectándose hay que asegurarlo. Cuatro frentes a cerrar.
6.1 - Lista blanca siempre activa
La lista blanca de la Parte 4.3 no es opcional en cuanto haya gente que conozca tu IP: es la diferencia entre "sólo entran mis compañeros" y "entra cualquiera del aula que averigüe la dirección". Déjala activada y, para que se mantenga al recrear el contenedor, añade al bloque environment del servicio mc:
ENABLE_WHITELIST: "TRUE"
WHITELIST: "TuNombre,NombreCompañero1,NombreCompañero2"
rcon-cli en la Parte 4.3, existe un fichero whitelist.json en el volumen y la variable WHITELIST puede no machacarlo. Para que el contenido de la variable mande siempre, añade también OVERRIDE_WHITELIST: "TRUE". Si no, simplemente sigue gestionando la lista con rcon-cli whitelist add/remove, que escribe directamente en ese fichero. Lo que sí surte efecto siempre es ENABLE_WHITELIST: activa o desactiva la comprobación.
6.2 - Operadores: los mínimos
Ser operador es poder total sobre el mundo y el servidor. Da op sólo a quien de verdad lo necesita. Un compañero que sólo quiere jugar no necesita ser operador.
6.3 - Mantener online-mode en true
Recuerda lo de la Parte 0.5: online-mode debe quedarse en true (su valor por defecto). Es lo que garantiza que cada jugador es quien dice ser. No lo toques. Si en algún tutorial de internet te dicen que lo pongas en false "para que entren más", están abriendo el servidor a cualquiera y saltándose las condiciones del juego.
6.4 - Cambiar la contraseña de RCON
La consola RCON tiene una contraseña, y la imagen trae una por defecto. Mientras sólo la uses con docker compose exec desde tu propio equipo el riesgo es bajo, pero la buena práctica es ponerle una propia. Añade al environment del servicio mc:
RCON_PASSWORD: "una_contraseña_larga_y_tuya"
Y, muy importante, no publiques el puerto de RCON (25575) en el bloque ports. Sólo el 25565, que es el del juego. RCON debe quedar accesible únicamente desde dentro, vía docker compose exec.
6.5 - Backups programados
El backup de la Parte 2.4 es manual. En producción se automatiza. La propia imagen itzg/minecraft-server tiene un proyecto hermano para backups automáticos, y también puedes programar el patrón de la Parte 2.4 con el Programador de tareas de Windows. Un servidor de juego sin backups automáticos es cuestión de tiempo que pierda semanas de trabajo de todos los que juegan en él.
De los cuatro frentes (lista blanca, operadores mínimos, online-mode, RCON), ¿cuál consideras más crítico para un servidor con gente conectándose y por qué? ¿Cuál es el que más gente se salta?
Parte 7 - Documentar el despliegue (25 min)
Como en la práctica 34, vas a documentar el despliegue completo: el documento que dejarías a un compañero para que pueda mantener el servidor si tú no estás.
FICHA DE DESPLIEGUE - SERVIDOR DE MINECRAFT
Anexo (opcional) - Abrir el servidor a internet con un túnel (45 min)
A.1 - Por qué hace falta un túnel y de qué tipo
En red local, dos equipos se ven directamente. Desde internet, no: hay un router que no deja entrar conexiones. La solución, igual que en la práctica 34, es un túnel saliente: tu equipo abre una conexión hacia fuera que se mantiene viva, y el tráfico de los jugadores entra por ahí, sin necesidad de abrir puertos del router.
Pero hay una diferencia con la práctica 34. Allí publicaste Nextcloud, que habla HTTP, y Cloudflare Tunnel es un túnel HTTP. Minecraft no habla HTTP: usa su propio protocolo sobre TCP. Necesita un túnel TCP genérico, que pase los bytes "en crudo". Por eso aquí se usa ngrok, que sí ofrece túneles TCP.
| Nextcloud (práctica 34) | Minecraft (este anexo) | |
|---|---|---|
| Protocolo | HTTP/HTTPS | Protocolo propio sobre TCP |
| Túnel adecuado | Cloudflare Tunnel (HTTP) | ngrok en modo TCP |
A.2 - Crear la cuenta y obtener el authtoken
- Crea una cuenta gratuita en
dashboard.ngrok.com(no pide tarjeta). - En el panel, busca la sección Your Authtoken y copia el token: una cadena larga de letras y números.
A.3 - Instalar el agente de ngrok en Windows
Aquí no hace falta tocar el docker-compose.yml ni añadir contenedores. La clave está en algo que ya tienes: la línea ports: "25565:25565" del compose hace que el servidor esté escuchando en el puerto 25565 de tu propio Windows. El agente de ngrok, instalado como un programa normal de Windows, sólo tiene que apuntar a ese puerto local.
Instala el agente. Desde PowerShell, con el gestor de paquetes de Windows:
winget install ngrok
Si winget no está disponible o falla, descarga el agente desde ngrok.com/download (sección Windows) y descomprímelo. Comprueba que ha quedado instalado:
ngrok version
ngrok no se reconoce como comando justo después de instalarlo con winget, cierra y vuelve a abrir PowerShell: la ventana ya abierta no se entera de los cambios en el PATH hasta que se reinicia.
Configura tu authtoken (el del paso A.2). Se hace una sola vez: ngrok lo guarda en tu perfil de usuario y no hay que repetirlo:
ngrok config add-authtoken pega_aqui_tu_authtoken
Levanta el túnel TCP apuntando al puerto 25565 que publica tu servidor:
ngrok tcp 25565
ngrok ocupa la ventana de PowerShell con un panel de estado. Fíjate en la línea Forwarding, que mostrará algo así:
Forwarding tcp://N.tcp.XX.ngrok.io:PUERTO -> localhost:25565
Esa dirección de la izquierda (sin el tcp:// de delante) es la que tus amigos de fuera ponen en Minecraft como dirección del servidor.
rcon-cli mientras tanto, abre otra ventana de PowerShell.
| ¿Cómo instalaste ngrok (winget / descarga manual)? | |
| Dirección pública que te ha dado ngrok | |
| ¿Entró alguien desde fuera de tu red? |
A.4 - Las pegas del plan gratuito
- El plan gratuito de ngrok permite un túnel a la vez.
- La dirección TCP cambia cada vez que paras ngrok y lo vuelves a lanzar. Igual que las URLs
trycloudflare.comde la práctica 34: es efímera por diseño. Cada vez que relancesngrok tcp 25565, mira la nueva línea Forwarding y reparte la dirección nueva. - Para una dirección fija haría falta un dominio propio y un plan de pago, o saltar a otro servicio. Fuera del alcance de esta práctica.
Compara las tres formas de "abrir" un servidor que has visto en el curso: red local directa (esta práctica), Cloudflare Tunnel HTTP (práctica 34) y ngrok TCP (este anexo). ¿Cuándo usarías cada una? ¿Qué tienen en común los dos túneles frente a abrir puertos del router?
Conclusiones y autoevaluación
Has montado, abierto y administrado un servidor de juego en una jornada. Sin Docker, calcula a ojo cuánto te habría llevado y cuántas cosas distintas habrías tenido que aprender (instalar la versión correcta de Java, configurar el servidor...). ¿Qué función concreta de Docker te ha ahorrado más tiempo?
Explica qué hace exactamente la línea ports: "25565:25565" del compose. ¿Por qué gracias a ella no tuviste que configurar nada más para que entraran compañeros de tu red? ¿Qué pasó en el Caso E cuando cambiaste el lado izquierdo?
Compara jugar en red local (lo que has hecho) con abrir el servidor a internet (el Anexo). ¿Qué ventajas e inconvenientes tiene cada opción en cuanto a simplicidad, alcance y seguridad? ¿Para el aula cuál es la sensata?
El responsable de un centro juvenil te pide montar un servidor de Minecraft para los chavales, que se conectarán desde los equipos de la sala. ¿Recomendarías este montaje? Lista al menos tres condiciones o medidas que pondrías antes de dárselo en uso.
Compara las prácticas 34 (Nextcloud) y 35 (Minecraft). ¿Qué conceptos se repiten exactamente igual? ¿Qué tuviste que hacer aquí que no hacía falta en la 34 (pista: el backup)?
Autoevaluación
| Aspecto | Logrado |
|---|---|
| Entiendo qué es un servidor de Minecraft y por qué containerizarlo resuelve problemas reales | |
He levantado el servidor con un único docker compose up -d | |
Entiendo el papel de la variable EULA | |
He probado que el mundo sobrevive a un compose down (sin -v) | |
| Sé hacer un backup correcto del mundo (con flush previo) y restaurarlo | |
Entiendo qué hace ports: "25565:25565" y cómo publica el servidor en la red | |
Sé averiguar la IP de mi equipo con ipconfig e identificar el adaptador correcto | |
| Se ha conectado al menos un compañero de mi red local al servidor | |
| Sé diagnosticar un problema de conexión: firewall vs aislamiento de clientes | |
| Sé usar la consola RCON: op, whitelist, kick, say... | |
| Entiendo la diferencia entre VANILLA y PAPER | |
| He provocado y resuelto los cinco fallos de la Parte 5 | |
He activado la lista blanca y dejado online-mode en true | |
| He rellenado la ficha de despliegue completa | |
| OPCIONAL He abierto el servidor a internet con un túnel TCP (Anexo) |