Un contenedor en ejecución conserva su antiguo límite de memoria cuando la configuración de Compose editada nunca se aplicó al cgroup activo de ese contenedor.
Cambiar el YAML no modifica por sí solo un contenedor existente, y un reinicio normal inicia el mismo contenedor con la misma configuración establecida durante su creación. La confusión también surge al comparar un límite de memoria estricto con una reserva, una asignación de swap, el ámbito principal de systemd o la configuración del heap de la aplicación. Diagnostica el valor efectivo del cgroup y el ID del contenedor antes de concluir que Docker ignoró el cambio.
Lee el límite del cgroup activo en lugar de confiar en el YAML
Registra el ID del contenedor, la hora de creación, la salida de inspección de Docker, la versión del cgroup y los archivos de control de memoria que utiliza el proceso en ejecución.
El kernel de Linux define memory.max como el límite estricto de memoria del cgroup, mientras que memory.high aplica presión de recuperación sin actuar como el mismo techo absoluto.
Si el cgroup activo todavía contiene el valor antiguo, la configuración no se aplicó. Si contiene el valor nuevo pero la monitorización no coincide, comprueba las unidades, la contabilización de la caché, el swap y las métricas del nivel de la aplicación.
Distingue entre reiniciar y recrear un contenedor
Compara el ID del contenedor antes y después del comando utilizado para implementar el cambio. Registra si el comando fue restart, up, create, una acción de la interfaz de un NAS o una actualización directa de Docker.
Docker indica que Compose restart no aplica cambios de configuración, porque reinicia los contenedores de servicio existentes.
Usa una actualización controlada de Compose que recree el servicio o una actualización de recursos activa compatible cuando corresponda. Conserva la salida de inspección anterior para poder verificar el campo modificado.
Valida el modelo final de Compose y el campo de memoria
Genera la configuración efectiva de Compose después de aplicar todos los archivos, perfiles y sustituciones de entorno. Comprueba que el límite pertenezca al servicio activo.
La especificación de Compose define mem_limit como un límite de memoria del servicio y exige coherencia cuando también se declaran límites de implementación equivalentes.
Un valor en un archivo de sustitución no utilizado, un perfil inactivo, un servicio escrito incorrectamente o una interfaz de Stack diferente no cambia el modelo implementado. Compara la configuración generada con la inspección de Docker.
Separa el límite estricto, la reserva y el swap
Registra el límite de memoria estricto, la reserva o el límite flexible, el límite de swap, el uso actual, el uso máximo y los eventos OOM. No trates todos los valores relacionados con la memoria como si fueran un único techo.
La documentación de control de recursos de systemd distingue MemoryHigh de MemoryMax y muestra que los cgroups principales pueden imponer límites adicionales a los servicios y contenedores.
Un contenedor puede parecer superar una reserva porque una reserva no equivale a un límite estricto. También puede consumir swap o caché de páginas que un panel excluye o muestra por separado.
Comprueba si el heap del entorno de ejecución tiene su propio límite
Para aplicaciones Java, registra la detección de la JVM compatible con contenedores, el heap máximo, la memoria directa, el metaspace, las pilas de los hilos y los indicadores transferidos por la imagen o la configuración de la aplicación.
Oracle documenta que la JVM dimensiona su heap a partir de las restricciones de memoria disponibles y permite que MaxRAMPercentage establezca la fracción del heap.
Cambiar el límite del contenedor puede no producir el heap esperado de la aplicación cuando permanece definido un -Xmx explícito o un porcentaje. Además, la memoria del heap no es el uso total de memoria del proceso.
Comprueba los límites de Node.js y de otras aplicaciones
Inspecciona los indicadores del entorno de ejecución, las variables de entorno, el número de trabajadores, las cachés y los objetivos internos de memoria. Compáralos con el límite del sistema operativo.
Node.js documenta max-old-space-size como límite del heap de V8, que puede permanecer sin cambios incluso después de que el contenedor reciba una asignación de cgroup mayor o menor.
El límite de un contenedor protege al host; no ajusta automáticamente todas las aplicaciones. Configura el entorno de ejecución por debajo del techo del contenedor y deja margen para las asignaciones nativas y la caché del sistema de archivos.
Aplica un cambio y verifícalo con una carga controlada
Genera el modelo final de Compose, recrea únicamente el servicio afectado, confirma el nuevo ID del contenedor y el cgroup activo, y después ejecuta una carga acotada mientras observas el uso y los eventos OOM.
El artículo de ZimaSpace Tech & AI Hub explica qué ocurre al alcanzar el límite activo de un contenedor; este artículo se centra en demostrar que un límite modificado se implementó realmente.
El problema se resuelve cuando la configuración generada, la inspección del contenedor, los archivos del cgroup, el heap del entorno de ejecución y el límite de fallo observado coinciden con la política prevista después de reiniciar.
Preguntas frecuentes
¿Reiniciar un contenedor aplica un límite de memoria de Compose modificado?
No. Normalmente, un reinicio utiliza la misma configuración del contenedor existente. Recrea el servicio o usa una actualización activa compatible.
¿Puede un contenedor superar temporalmente su límite de memoria estricto?
La contabilización del kernel y la recuperación pueden mostrar brevemente valores cercanos o ligeramente superiores al límite, pero un uso sostenido que no pueda recuperarse al alcanzar el límite estricto provoca la gestión OOM del cgroup.
¿Por qué la aplicación sigue mostrando el tamaño de heap antiguo?
El entorno de ejecución de la aplicación puede tener un indicador de heap explícito o calcular un porcentaje únicamente al iniciarse. Recrea o reinicia la aplicación después de validar el límite del contenedor.
Soporte y Consejos
Más para leer

¿Por qué restaurar un volumen de Docker recrea el contenido de los archivos, pero elimina los atributos extendidos?
Un diagnóstico de restauración de volúmenes que abarca el inventario de atributos extendidos, las opciones de tar y Rsync, los espacios de nombres, la...

¿Por qué reiniciar un proxy inverso invalida todas las sesiones de una aplicación autoalojada?
Un diagnóstico de pérdida de sesión que abarca el alcance del reinicio, la propiedad de las cookies, la rotación de secretos, las sesiones respaldadas...

¿Por qué un alias de red de Compose deja de resolverse después de recrear la pila con un nombre de proyecto nuevo?
Un diagnóstico de DNS de Compose que abarca los nombres de proyecto, los alias con ámbito de red, las redes externas, el DNS integrado,...

