Planificador de RAM Docker
Planifique el uso de memoria de contenedores contra su RAM disponible.
Agregar contenedor
Services
Custom
RAM total usado
0 MB
Restante
3584 MB
Reservado del sistema
512 MB
Fits comfortably
Good headroom for scaling and memory spikes.
¿Qué es una calculadora de RAM para Docker?
Una calculadora de RAM para Docker estima la memoria total necesaria para ejecutar un conjunto de contenedores Docker en un servidor o máquina de homelab. Cada servicio en contenedor (base de datos, servidor web, monitorización, servidor multimedia) tiene requisitos específicos de memoria. Esta herramienta te ayuda a planificar tus necesidades de hardware sumando las asignaciones de memoria de los contenedores con la sobrecarga del sistema operativo y el motor Docker.
Quedarse sin RAM es la causa más común de bloqueos de contenedores Docker e inestabilidad del servidor. A diferencia de la CPU, que se puede compartir en el tiempo, la RAM es un límite duro: cuando un contenedor supera su asignación de memoria, Docker lo mata (OOM — Out of Memory). Una buena planificación previene caídas inesperadas y te ayuda a decidir si actualizar el servidor u optimizar la pila.
Cómo usar esta herramienta
Añade los contenedores que planeas ejecutar y especifica sus requisitos de memoria. La herramienta suma el total, añade la sobrecarga del SO y el motor Docker, y muestra la RAM total recomendada. Avisa si tu configuración planificada supera las configuraciones de hardware típicas.
Límites de memoria frente a reservas de memoria
Docker ofrece dos parámetros distintos para controlar cuánta RAM puede usar un contenedor: los límites de memoria y las reservas de memoria. Con frecuencia se confunden, pero tienen propósitos muy diferentes.
Un límite de memoria (configurado con --memory o mem_limit en un archivo Compose) es un techo fijo. Docker lo aplica a través del subsistema de cgroups (grupos de control) de Linux. El contenedor nunca puede asignar más memoria de la indicada; si lo intenta, el kernel de Linux activa el OOM killer.
- --memory / mem_limit: el límite máximo estricto. El contenedor no puede superarlo. Protege al host de procesos desbordados.
- --memory-reservation / mem_reservation: una sugerencia flexible para el planificador. El planificador de Docker Swarm la usa al decidir dónde colocar los servicios. NO impide que el contenedor use más memoria; es simplemente una garantía mínima que Docker intenta respetar.
- Una buena práctica habitual: establece la reserva en el consumo esperado en reposo y el límite en el máximo que estás dispuesto a permitir. Por ejemplo, un contenedor que consume 200 MB en reposo pero puede llegar a 600 MB en picos podría configurarse con reservation=200m y limit=600m.
Si omites ambos parámetros, el contenedor no tiene límite y puede consumir toda la RAM disponible en el host. En un servidor monopropósito esto puede ser aceptable, pero en un homelab con muchos servicios supone un riesgo considerable.
Qué ocurre cuando un contenedor alcanza su límite de memoria
Cuando el uso de memoria de un contenedor alcanza el valor establecido en --memory, el OOM killer del kernel de Linux termina el proceso más voraz del contenedor. Docker registra esto como código de salida 137, que corresponde a la señal POSIX 9 (SIGKILL). Puedes verlo en docker ps --all o en los logs del contenedor como «Exited (137)».
El código de salida 137 no significa que tu aplicación haya fallado por un error; significa que el kernel la mató forzosamente porque el contenedor superó el límite de RAM configurado. Si ves salidas 137 repetidas en una aplicación estable, el límite de memoria es demasiado bajo o la carga de trabajo ha crecido más allá de la estimación original. Aumenta el límite y vuelve a monitorizar con docker stats.
Consideraciones de memoria según el entorno de ejecución
Los distintos entornos de ejecución y motores de bases de datos gestionan la memoria de formas muy diferentes. Establecer un límite de memoria en un contenedor sin tener en cuenta el comportamiento del entorno de ejecución es una de las causas más comunes de terminaciones inesperadas por OOM.
- JVM (Java, Kotlin, Scala): la JVM reserva el heap al arrancar. Sin parámetros explícitos puede reclamar una gran fracción de la RAM del sistema desde el inicio. Define siempre -Xmx (heap máximo) a un valor inferior al límite de memoria de Docker; una guía habitual es dejar al menos un 25% de margen sobre -Xmx para memoria fuera del heap, la sobrecarga del recolector de basura y las bibliotecas nativas.
- Node.js: V8 tiene un límite de heap por defecto (alrededor de 1,5 GB en sistemas de 64 bits en versiones antiguas). Si tu límite de Docker es inferior, el proceso puede ser eliminado por OOM antes de que V8 active la recolección de basura. Usa --max-old-space-size (en MB) para limitar el heap de la generación antigua de V8 y fíjalo por debajo del límite de memoria de Docker.
- Bases de datos (PostgreSQL, MariaDB, MySQL): las bases de datos son consumidores agresivos de memoria por diseño: almacenan en caché las páginas más activas en su pool de buffers compartidos. El parámetro shared_buffers de PostgreSQL tiene un valor por defecto de 128 MB, pero habitualmente se ajusta al 25% de la RAM disponible en servidores dedicados. Dentro de un contenedor, ajusta shared_buffers para que quepa dentro de tu límite de memoria o la base de datos será terminada de forma inesperada bajo carga.
- Servidores multimedia (Jellyfin, Plex): la transcodificación consume mucha memoria. Una sola transcodificación en 4K puede requerir entre 1 y 3 GB además del consumo en reposo. Si habilitas la transcodificación acelerada por hardware, el panorama de memoria cambia significativamente. Comprueba el uso real de tu servidor bajo carga real antes de fijar los límites.
Requisitos comunes de memoria por contenedor
Las cifras siguientes son rangos de referencia aproximados únicamente para planificación; el uso real varía considerablemente según la configuración, el tamaño del conjunto de datos, el número de usuarios y las funciones habilitadas. Mide siempre con docker stats después de ejecutar tu carga de trabajo real.
- PostgreSQL: 256MB-1GB+ según el tamaño de la base de datos y la complejidad de las consultas.
- Nginx/Caddy: 50-128MB para uso típico como proxy inverso.
- Grafana + Prometheus: 256MB + 512MB-2GB para pilas de monitorización.
- Home Assistant: 256MB-512MB para automatización del hogar.
- Plex/Jellyfin: 1-4GB según el transcodificado y el tamaño de la biblioteca.
- Proxies inversos ligeros (Traefik, Caddy, Nginx): generalmente entre 30 y 150 MB en reposo; son de los servicios más eficientes en memoria que puedes ejecutar.
- Stacks de monitorización (Prometheus + Grafana): Prometheus escala con el número de series temporales que recopila y almacena, desde unos pocos cientos de MB hasta varios GB en entornos grandes. Grafana en sí es relativamente ligero, con unos 100–300 MB.
Ejemplo de dimensionamiento: un homelab típico con Raspberry Pi 4 (8 GB)
Para ver cómo se acumula la asignación de RAM, imagina una Raspberry Pi 4 con 8 GB ejecutando un pequeño stack autoalojado:
- SO anfitrión (Raspberry Pi OS Lite): ~300–500 MB reservados para el kernel, procesos del sistema y el propio motor de Docker
- Pi-hole (bloqueador de anuncios DNS): límite de 128 MB — servicio ligero con baja sobrecarga
- Vaultwarden (gestor de contraseñas compatible con Bitwarden): límite de 128 MB — binario Rust muy liviano
- Home Assistant: límite de 512 MB — basado en Python, crece con las automatizaciones e integraciones
- Jellyfin (servidor multimedia, transcodificación por software desactivada): límite de 1024 MB — escala con el tamaño de la biblioteca
- Portainer (interfaz de gestión de contenedores): límite de 256 MB
Sumando estos límites: 500 (host) + 128 + 128 + 512 + 1024 + 256 = aproximadamente 2,5 GB asignados. En un dispositivo de 8 GB quedan unos 5,5 GB libres, un margen cómodo para caché, picos y contenedores futuros. En una Pi 4 de 2 GB, este mismo stack estaría sobre-comprometido incluso antes de considerar los picos. La calculadora anterior realiza exactamente esta aritmética para cualquier combinación de servicios que elijas.
Por qué la sobre-asignación de RAM es arriesgada
Sobre-asignar significa planificar un stack cuyos límites de memoria combinados superan la RAM física disponible para el SO anfitrión. Docker no lo impide: acepta perfectamente un archivo Compose que asigna 10 GB entre contenedores en una máquina de 4 GB. El riesgo se materializa en tiempo de ejecución: cuando el uso real de todos los contenedores se aproxima a la RAM física, el kernel comienza a hacer swap de forma agresiva. El swap en tarjetas SD y unidades USB (almacenamiento habitual en homelabs) es órdenes de magnitud más lento que la RAM y puede provocar bloqueos de todo el sistema.
El SO anfitrión también necesita margen más allá de lo que usan los contenedores. La caché de páginas de Linux, los buffers del kernel y los daemons del sistema compiten por la RAM. Como regla general, nunca planifiques un stack que deje menos del 10–15% de la RAM total libre para el host tras sumar los límites de los contenedores. En un dispositivo de 4 GB, eso significa mantener al menos 400–600 MB sin asignar.
Consejos de optimización de memoria
Establece límites de memoria en todos los contenedores (docker run --memory=512m) para evitar que un único contenedor consuma toda la RAM disponible. Usa imágenes basadas en Alpine, que son más pequeñas y consumen menos memoria. Monitoriza el uso real con 'docker stats' antes de tomar decisiones finales de dimensionamiento. Deja al menos 1-2GB libres para el SO anfitrión, la caché de archivos y la sobrecarga de Docker. El espacio swap puede ser una red de seguridad pero no se debe depender de él para operaciones normales.
Errores comunes al dimensionar la RAM de Docker
- No establecer ningún límite: sin límites --memory, cualquier contenedor puede consumir toda la RAM del host, dejando sin servicio a todos los demás.
- Confundir reserva con límite: establecer una mem_reservation alta no limita el uso; un contenedor con una reserva grande y sin límite puede agotar igualmente la RAM del host.
- Ignorar la sobrecarga del SO anfitrión: asignar el 100% de la RAM física entre contenedores no deja nada para el kernel, el motor de Docker ni los procesos en segundo plano.
- Dimensionar a partir de la documentación de la imagen en lugar del uso real: las imágenes oficiales suelen indicar requisitos mínimos. El RSS real bajo tu carga de trabajo real puede ser entre 2 y 5 veces mayor. Verifica siempre con docker stats.
- Olvidar los ajustes de heap del entorno de ejecución: los contenedores para aplicaciones JVM o Node que no tienen un límite de heap configurado intentarán usar tanta memoria como permita el límite del contenedor, o lo superarán y provocarán un OOM kill.
Preguntas frecuentes
¿Cuánta sobrecarga de RAM necesita Docker en sí?
El propio motor de Docker usa unos 100-200MB de RAM. El SO Linux anfitrión normalmente necesita 500MB-1GB para una instalación mínima de servidor. Combinados, planifica unos 1-1,5GB de sobrecarga antes de las asignaciones a contenedores. En un servidor de 16GB, dispones realmente de unos 14-15GB para contenedores.
¿Qué pasa cuando un contenedor se queda sin memoria?
Cuando un contenedor supera su límite de memoria, el OOM (Out of Memory) killer del kernel Linux lo termina. Docker lo reporta como código de salida 137. Sin límites de memoria, un contenedor que se comporta mal puede consumir toda la RAM del sistema, pudiendo bloquear otros contenedores y el SO anfitrión. Establece siempre límites de memoria explícitos y monitoriza el uso.
¿Debo configurar swap para los contenedores de Docker?
Docker permite establecer un límite de swap por separado con --memory-swap. Si configuras --memory=512m y --memory-swap=1g, el contenedor dispone de 512 MB de RAM más 512 MB de swap. El swap ofrece una red de seguridad que evita los OOM kill inmediatos, pero depender del swap para el funcionamiento normal degrada el rendimiento de forma significativa, especialmente en almacenamiento flash. Usa el swap como último recurso, no como sustituto de RAM suficiente. En sistemas sin el parámetro --memory-swap explícito, Docker usa por defecto el doble del límite de memoria como swap.
¿Cómo sé cuánta RAM usan realmente mis contenedores en ejecución?
Ejecuta docker stats para ver en tiempo real el uso de CPU, memoria y los límites de memoria de cada contenedor en ejecución. La columna MEM USAGE muestra el RSS (resident set size) actual del contenedor. Compáralo con tus límites configurados para ver el margen disponible en cada contenedor. Para una instantánea puntual usa docker stats --no-stream. También puedes inspeccionar un contenedor concreto con docker inspect <nombre> y buscar el campo MemoryStats.