Un VPS con suficiente memoria puede alojar varios servidores de juegos a la vez, siempre que cada uno tenga sus propios puertos, sus datos separados y un límite de recursos que impida que uno deje sin memoria a los demás. En este tutorial usarás Docker Compose en Ubuntu 24.04 para levantar dos servidores de Minecraft Java (supervivencia y creativo) y un servidor dedicado de Valheim. Al terminar sabrás añadir, parar y respaldar cada servidor de forma independiente.
Requisitos previos
- Un VPS con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 4 vCPU y 12 GB de RAM para los tres servidores de este ejemplo.
- Un usuario no root con privilegios
sudo. - Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker. Si aún no los tienes, sigue la guía de instalación de Docker de CubePath.
- Tu usuario en el grupo
docker, o anteponersudoa los comandosdocker.
Paso 1: Calcular los recursos
La memoria es el recurso que se agota primero. Cada servidor necesita su memoria de juego más un margen para el propio proceso, y el sistema operativo necesita al menos 1 GB libre. Estas cifras son un punto de partida razonable:
| Servidor | Jugadores | RAM asignada | CPU |
|---|---|---|---|
| Minecraft Java (Paper, vanilla) | 10 a 20 | 3 a 4 GB | 1 a 2 núcleos |
| Minecraft Java con mods | 10 a 20 | 6 a 8 GB | 2 núcleos |
| Valheim | hasta 10 | 3 a 4 GB | 2 núcleos |
Para este tutorial:
mc-survival: 4 GB de límite, 3 GB de heap de Java, 2 CPU.mc-creative: 3 GB de límite, 2 GB de heap de Java, 1 CPU.valheim: 4 GB de límite, 2 CPU.
En total son 11 GB como máximo, lo que deja 1 GB para el sistema en un VPS de 12 GB. Los límites de CPU pueden sumar más que los núcleos reales, porque rara vez todos los servidores están a plena carga a la vez; los de memoria no.
Comprueba los recursos de tu servidor:
nproc
free -h
df -h /
Paso 2: Crear la estructura de directorios
Guarda todo en un único directorio, con una carpeta de datos por servidor. Así cada mundo se respalda o se borra sin afectar a los demás:
mkdir -p ~/gameservers/{mc-survival,mc-creative,valheim/config,valheim/data}
cd ~/gameservers
Paso 3: Definir los servidores en Docker Compose
Usarás dos imágenes de la comunidad muy mantenidas: itzg/minecraft-server, que descarga y configura el servidor de Minecraft a partir de variables de entorno, y lloesche/valheim-server, que instala el servidor dedicado de Valheim con SteamCMD.
Cada Minecraft escucha en el puerto 25565 dentro de su contenedor; en el host, el segundo se publica en el 25566 para que no choquen. Valheim usa los puertos UDP 2456 y 2457.
Crea el archivo de Compose:
nano ~/gameservers/compose.yaml
Añade este contenido. Sustituye your_valheim_password por una contraseña de al menos 5 caracteres que no contenga el nombre del servidor:
services:
mc-survival:
image: itzg/minecraft-server:latest
container_name: mc-survival
restart: unless-stopped
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "LATEST"
MEMORY: "3G"
MOTD: "Servidor de supervivencia"
DIFFICULTY: "normal"
MAX_PLAYERS: "20"
TZ: "Europe/Madrid"
ports:
- "25565:25565/tcp"
volumes:
- ./mc-survival:/data
mem_limit: 4g
cpus: 2
mc-creative:
image: itzg/minecraft-server:latest
container_name: mc-creative
restart: unless-stopped
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "LATEST"
MEMORY: "2G"
MOTD: "Servidor creativo"
MODE: "creative"
MAX_PLAYERS: "10"
TZ: "Europe/Madrid"
ports:
- "25566:25565/tcp"
volumes:
- ./mc-creative:/data
mem_limit: 3g
cpus: 1
valheim:
image: lloesche/valheim-server:latest
container_name: valheim
restart: unless-stopped
stop_grace_period: 2m
cap_add:
- sys_nice
environment:
SERVER_NAME: "Mi servidor Valheim"
WORLD_NAME: "Midgard"
SERVER_PASS: "your_valheim_password"
SERVER_PUBLIC: "true"
TZ: "Europe/Madrid"
ports:
- "2456-2457:2456-2457/udp"
volumes:
- ./valheim/config:/config
- ./valheim/data:/opt/valheim
mem_limit: 4g
cpus: 2
Qué hace cada ajuste importante:
EULA: "TRUE"acepta la licencia de Minecraft; sin ella el servidor no arranca. Hazlo solo si has leído y aceptas el EULA de Mojang.MEMORYfija el heap de Java. Déjalo siempre por debajo demem_limit, porque la JVM usa memoria adicional fuera del heap. Si ambos valores coinciden, el kernel matará el contenedor por falta de memoria.mem_limitycpusson límites duros de Docker: un servidor con una fuga de memoria se reinicia solo, en lugar de tumbar a los otros dos.restart: unless-stoppedarranca los servidores con el sistema, salvo los que hayas parado a mano.stop_grace_period: 2mda tiempo a Valheim para guardar el mundo al detenerse.
Valida el archivo antes de arrancar:
docker compose config --quiet && echo "compose.yaml correcto"
Paso 4: Arrancar los servidores
Descarga las imágenes y levanta los tres servidores en segundo plano:
docker compose up -d
El primer arranque tarda varios minutos: Minecraft descarga Paper y genera el mundo, y Valheim descarga el servidor dedicado (más de 1 GB). Sigue el progreso de cada uno:
docker compose logs -f mc-survival
El servidor de Minecraft está listo cuando aparece una línea como esta (pulsa Ctrl+C para salir de los logs):
mc-survival | [12:04:31 INFO]: Done (18.402s)! For help, type "help"
Comprueba el estado de todos los contenedores:
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
NAME STATUS PORTS
mc-creative Up 3 minutes (healthy) 0.0.0.0:25566->25565/tcp
mc-survival Up 3 minutes (healthy) 0.0.0.0:25565->25565/tcp
valheim Up 3 minutes 0.0.0.0:2456-2457->2456-2457/udp
Las imágenes de Minecraft incluyen rcon-cli para enviar comandos a la consola del servidor. Úsalo para confirmar que responde:
docker exec mc-survival rcon-cli list
There are 0 of a max of 20 players online:
Paso 5: Abrir los puertos en el firewall
Docker publica los puertos insertando sus propias reglas en iptables, que se evalúan antes que las de UFW. Eso significa que los puertos del archivo de Compose quedan accesibles desde Internet aunque UFW no los permita. Aun así, añade las reglas en UFW para que el firewall documente lo que está expuesto y siga protegiendo SSH:
sudo ufw allow OpenSSH
sudo ufw allow 25565:25566/tcp comment 'Minecraft'
sudo ufw allow 2456:2457/udp comment 'Valheim'
sudo ufw enable
sudo ufw status
Importantecomo Docker salta UFW, nunca publiques en
portsservicios que no deban ser públicos, como una base de datos o RCON. Si necesitas acceder a uno desde el propio servidor, publícalo solo en local:"127.0.0.1:25575:25575".
Conéctate desde tu cliente de Minecraft a your_server_ip (supervivencia) y a your_server_ip:25566 (creativo). En Valheim, añade el servidor como your_server_ip:2456 desde la lista de servidores.
Paso 6: Vigilar el consumo de recursos
Muestra el uso de CPU y memoria de cada contenedor frente a su límite:
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"
NAME CPU % MEM USAGE / LIMIT MEM %
mc-survival 38.52% 3.21GiB / 4GiB 80.25%
mc-creative 6.10% 2.14GiB / 3GiB 71.33%
valheim 55.20% 2.87GiB / 4GiB 71.75%
Una CPU por encima del 100 % en un contenedor con cpus: 2 es normal (100 % equivale a un núcleo). Fíjate sobre todo en la memoria: si un contenedor ronda el 95 % de su límite de forma constante, súbelo o reduce el heap. Para saber si Docker ha matado algún contenedor por memoria:
docker inspect --format '{{.Name}} OOMKilled={{.State.OOMKilled}} Restarts={{.RestartCount}}' mc-survival mc-creative valheim
Paso 7: Gestionar cada servidor por separado
Todos los comandos se ejecutan desde ~/gameservers y aceptan el nombre de un servicio para actuar solo sobre él.
Reinicia un servidor sin tocar los demás:
docker compose restart mc-creative
Detén un servidor que no se usa para liberar su memoria:
docker compose stop valheim
Actualiza las imágenes y recrea solo los contenedores que hayan cambiado:
docker compose pull
docker compose up -d
Para añadir un cuarto servidor, copia un bloque de servicio en compose.yaml, cambia el nombre, el directorio de datos y el puerto del host (por ejemplo, 25567:25565/tcp), abre ese puerto en UFW y ejecuta docker compose up -d.
Paso 8: Hacer copias de seguridad de los mundos
Copiar los archivos de un mundo mientras el servidor escribe en ellos puede dar lugar a una copia corrupta. Para Minecraft, desactiva el guardado automático, fuerza un guardado, copia y vuelve a activarlo:
mkdir -p ~/backups
docker exec mc-survival rcon-cli save-off
docker exec mc-survival rcon-cli save-all flush
tar -czf ~/backups/mc-survival-$(date +%F).tar.gz -C ~/gameservers mc-survival
docker exec mc-survival rcon-cli save-on
Valheim guarda el mundo al detenerse, así que la forma más segura es pararlo unos segundos:
cd ~/gameservers
docker compose stop valheim
tar -czf ~/backups/valheim-$(date +%F).tar.gz -C ~/gameservers valheim/config
docker compose start valheim
Comprueba que las copias contienen los mundos:
tar -tzf ~/backups/mc-survival-$(date +%F).tar.gz | head
Guarda las copias fuera del VPS (en otro servidor o en almacenamiento de objetos): una copia en el mismo disco no te protege de la pérdida del servidor.
Solución de problemas
Un contenedor se reinicia una y otra vez. Revisa sus últimas líneas de log con docker compose logs --tail 50 mc-survival. Las causas más comunes son EULA sin aceptar, un heap (MEMORY) igual o mayor que mem_limit, o falta de espacio en disco.
Bind for 0.0.0.0:25565 failed: port is already allocated. Otro contenedor o proceso usa ese puerto en el host. Localízalo con sudo ss -tulpn | grep 25565 y cambia el puerto del host en compose.yaml.
Valheim no aparece en la lista pública. El registro en la lista de servidores puede tardar varios minutos tras el primer arranque. Mientras tanto, conéctate directamente con your_server_ip:2456 y confirma en docker compose logs valheim que el servidor ha terminado de cargar.
Conclusión
Tienes tres servidores de juegos aislados en contenedores dentro de un mismo VPS, cada uno con sus puertos, sus datos y límites de CPU y memoria que protegen a los demás. A partir de aquí, automatiza las copias con un temporizador de systemd o cron, protege los puertos del juego con reglas de rate limiting y revisa docker stats durante las horas punta para ajustar los límites antes de añadir más servidores.
