Si alguna vez tienes una idea para automatizar esto, porque realmente es una solución muy limpia fijar manualmente el límite, es una locura que LXC no aísle esta parte…
Si encuentro algo te aviso
Era yo con mi Gladys bajo LXC.
También miraré si encuentro una manera de determinar la RAM exacta expuesta por Proxmox.
He buscado un poco, pero cada vez me devuelve la RAM física total y no la expuesta a mi LXC.
Le hice la pregunta a la IA y esto es lo que obtuve como respuesta
Gladys debería usar una función de cálculo de RAM más inteligente al iniciar el servicio DuckDB. Aquí está el algoritmo objetivo :
1. **Verificar el Cgroup (El límite real) :** Leer `/sys/fs/cgroup/memory.max`.
* Si es un número (ej: 8 Go) : Usamos este valor como base.
* Si es `max` o un error : Usamos `os.totalmem()` (32 Go) como base.
2. **Aplicar el porcentaje (30%) :** Calculamos el 30% de la base elegida.
3. **Aplicar un "Techo de Seguridad" (El freno) :** Incluso en un servidor de 128 Go, DuckDB en Gladys no necesita 40 Go de RAM para almacenar historiales de temperatura.
* Limitamos el resultado a **2 Go** (valor ampliamente suficiente para el 99% de los usuarios).
* En un Raspberry Pi (2 Go) :** DuckDB tomará ~600 Mo (30%). Es perfecto.
* En un LXC Proxmox (8 Go en host 32 Go) :
* Si Gladys detecta los 8 Go → tomará 2.4 Go, pero será limitada por el techo a **2 Go**.
* Si Gladys falla al detectar y ve 32 Go → querría 9 Go, pero será limitada a **2 Go**.
Incluso propone un ejemplo de código:
const fs = require('fs');
const os = require('os');
function getDuckDbMemoryLimit() {
// 1. Check ENV variable
if (process.env.DUCKDB_MEMORY_LIMIT) return process.env.DUCKDB_MEMORY_LIMIT;
const SAFETY_CAP_GB = 2; // Techo de seguridad para la domótica
let totalDetectedRam = os.totalmem();
// 2. Try to read Cgroup limit (LXC/Docker)
try {
const cgroupLimit = fs.readFileSync('/sys/fs/cgroup/memory.max', 'utf8').trim();
if (cgroupLimit !== 'max') {
totalDetectedRam = parseInt(cgroupLimit, 10);
}
} catch (e) {
// Fallback to os.totalmem()
}
// 3. Calculate 30% of detected RAM
const calculatedLimit = totalDetectedRam * 0.30;
// 4. Return the minimum between calculated limit and Safety Cap
const safetyCapBytes = SAFETY_CAP_GB * 1024 * 1024 * 1024;
return Math.min(calculatedLimit, safetyCapBytes);
}
La IA se equivocó en las 2 propuestas desafortunadamente ![]()
Como se probó anteriormente, /sys/fs/cgroup/memory.max no contiene el valor de RAM disponible.
Para la idea del techo de seguridad, es un poco la solución fácil y no estoy de acuerdo con su análisis. Un usuario que tenga 16 GB de RAM disponibles para Gladys se beneficiará ampliamente de tener más RAM para DuckDB si tiene muchos datos y curvas complejas, como en el caso del seguimiento de energía.
Limitar a un valor arbitrario limitaría el rendimiento para aquellos que tienen un sistema rico en RAM, es una pena ![]()
/sys/fs/cgroup/memory.max devuelve max
En este caso, para un LXC en Proxmox, no veo solución sin limitar manualmente en docker run o docker compose.
He probado muchas cosas, pero cada vez me devolvía la RAM de Proxmox, no la del LXC.
¡Qué pena! Voy a actualizar la documentación.
Es increíble esta historia, uno podría pensar que el aislamiento está bien hecho y que cada contenedor solo ve lo que debería ver.
Sí, yo también lo pensaba.
Por el contrario, como dice @prohand, no hay este problema con una máquina virtual bajo Proxmox.
Entonces, como la IA cuenta muchas tonterías, le pregunté a la IA ![]()
Con Perplexity, tengo esto:
mount | grep cgroup2
cat /sys/fs/cgroup/memory.current
et funciona bien en mi LXC que tiene 6 Go de RAM:
root@gladys:~# mount | grep cgroup2
none on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
root@gladys:~# cat /sys/fs/cgroup/memory.current
6377263104
root@gladys:~# echo $(( $(cat /sys/fs/cgroup/memory.current) / 1000 / 1000 ))" Mo"
6377 Mo
root@gladys:~# echo $(( $(cat /sys/fs/cgroup/memory.current) / 1000 / 1000 / 1000 ))" Go"
6 Go
et el otro método (no 100% fiable al parecer) sería:
root@gladys:~# cat /proc/meminfo
MemTotal: 6291456 kB
EDICIÓN: lo de arriba es para cgroup2, para cgroup v1:
En cgroup v1, el equivalente de memory.current se llama memory.usage_in_bytes.
En el contenedor LXC en cgroup v1, puedes hacer:
bash
# Uso actual de memoria en MiB
echo $(( $(cat /sys/fs/cgroup/memory/memory.usage_in_bytes) / 1024 / 1024 ))" MiB"
# Uso actual de memoria en GiB
echo $(( $(cat /sys/fs/cgroup/memory/memory.usage_in_bytes) / 1024 / 1024 / 1024 ))" GiB"
memory.usage_in_bytes = memoria actualmente utilizada por el cgroup (anónima + caché + buffers).
¡Ah, interesante!
@Will_71 si haces:
docker exec -it gladys cat /sys/fs/cgroup/memory.current
¿Ves el valor correcto?
Acabo de intentarlo y no es fiable, especialmente al inicio.
La primera vez que lo intenté me devolvió 8 Go, pero tengo 16 Go.

Cuando cambié mi RAM el otro día no reinicié el LXC.
Por lo tanto, lo reinicié y ahora el valor aumenta poco a poco
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1023455232
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1027911680
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1029660672
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1031991296
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1029668864
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1030901760
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1029951488
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1030709248
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1030946816
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1031671808
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1031319552
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1022386176
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1024593920
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1044897792
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1045057536
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1279713280
root@saga:~# docker exec -it gladys cat /sys/fs/cgroup/memory.current
1279754240
SI convierto el valor a un formato mejor con la fórmula de @mutmut
root@saga:~# docker exec -it gladys echo $(( $(cat /sys/fs/cgroup/memory.current) / 1000 / 1000 / 1000 ))" Go"
1 Go
Algunas pruebas más en relación con tu solicitud para @Will_71.
Si ejecuto docker exec -it gladys cat /sys/fs/cgroup/memory.current en mi LXC o directamente cat /sys/fs/cgroup/memory.current en el contenedor Gladys, veo 4 GB cada vez.
Parece corresponder a los 4 GB que asigné al principio al crear mi LXC, y debido a las fugas de memoria que tuve, aumenté la RAM a 6 GB.
Pero ¿por qué no veo los 6 GB actuales? Es una buena pregunta que voy a investigar.
En cuanto a cat /proc/meminfo ejecutado en el contenedor Gladys, me devuelve los 16 GB de mi host, por lo que no es correcto.
Al mirar la documentación de Proxmox para la creación/edición de la RAM, parece que Proxmox se basa en cgroup v1:
Y siguiendo el comentario de @Will_71, también tengo un
memory.current de Docker que aumenta y disminuye muy lentamente directamente en el LXC que me indica 4GB también Parece que la RAM se asigna dinámicamente al LXC, raro.
EDICIÓN:
Esto parece confirmarse aquí:
El seguimiento del consumo también se mejora gracias a memory.current, que muestra el consumo en tiempo real.
Creo que sí, es gestionado dinámicamente, porque cada vez que se ha caído por falta de RAM, he aumentado el valor en Proxmox y el LXC se ha reiniciado sin reiniciar.
En el archivo de configuración de LXC (directamente en el host), se puede ver claramente que es cgroup2 y se tiene el valor correcto de RAM asignada al LXC:
Tengo la impresión de que Proxmox ofrece toda la RAM del host a los contenedores y solo entrega lo que se solicita en el archivo de configuración, lo que debe permitir modificar la RAM sobre la marcha sin problemas con una limitación puramente de software.
@Will_71
Acabo de ver que hay un subdirectorio .lxc en cgroup, quizás haya cosas que recuperar de ahí.
¿Qué obtienes si ejecutas:
docker exec -it gladys cat /sys/fs/cgroup/.lxc/memory.current
En mi caso tengo un número pequeño pero estable: 634880
no tengo una carpeta .lxc en cgroup
ok
¿Y qué valor para:
docker exec -it gladys cat /sys/fs/cgroup/memory.peak
Esta me da mis 6 GB (o casi)
EDIT: al revisar otros LXC, sigue sin ser la variable correcta ![]()
eso me deja con 7.6 GB de mis 16 GB
He avanzado bastante en el tema y parece muy complicado obtener fácilmente la cantidad real de RAM desde el docker de Gladys ![]()
De hecho, este siempre tomará la cantidad del host, incluso si el LXC proporciona la cantidad correcta.
La única solución que he podido probar y validar hasta ahora es pasar en el docker run o compose la cantidad de RAM que queremos.
Un ejemplo con docker-compose
services:
gladys:
image: gladysassistant/gladys:v4
...
mem_limit: 6g # cantidad de RAM asignada al LXC (aquí, 6 GB)
memswap_limit: 7g # cantidad de RAM+swap (aquí, 1 GB de swap)
Una vez reiniciado, obtengo estos valores que luego se pueden utilizar:
root@gladys-test:~# docker inspect gladys | grep -i memory
"Memory": 6442450944,
"MemoryReservation": 0,
"MemorySwap": 7516192768,
"MemorySwappiness": null,
root@gladys-test:~# docker exec -it gladys cat /sys/fs/cgroup/memory.max
6442450944
root@gladys-test:~# docker exec -it gladys cat /sys/fs/cgroup/memory.swap.max
1073741824
Para la anécdota, a través de Perplexity:
Es un comportamiento normal y conocido con Docker en LXC sin privilegios + nesting=1 en Proxmox: lxcfs expone la RAM correcta de LXC (4 GB) a nivel de host del contenedor, pero Docker (y sus contenedores) ven la RAM del host (16 GB) porque nesting propaga el namespace cgroup sin limitar
/proc/meminfode Docker.
- lxcfs reescribe
/proc/meminfodel LXC root →free -mLXC = 4 GB.- Docker con nesting crea sus propios cgroups hijos → su
/proc/meminfolee el cgroup padre (LXC limit) pero a menudo recurre al host si no se propaga.- Sin privilegios + fuse-overlayfs (script tteck) lo acentúa: Docker ignora lxcfs LXC.
