La pregunta que todo homelabber termina haciéndose
Ya tienes Proxmox funcionando, quizás un mini PC Beelink EQ12 (~$189) zumbando en silencio en un estante, y quieres autoalojar un montón de servicios: Vaultwarden, Nextcloud, Uptime Kuma, Home Assistant, Immich. Entonces aparece la pregunta: ¿uso contenedores LXC o levanto una VM con Docker?
Es uno de los temas más debatidos en las comunidades r/homelab y r/selfhosted, y con razón: ambos enfoques funcionan, pero tienen diferencias importantes según tu caso de uso. Esta es la comparación honesta.
Qué es realmente LXC (y qué no es)
LXC (Linux Containers) es la capa nativa de contenedores de Proxmox. No es Docker. Los contenedores LXC comparten directamente el kernel del host: no hay hipervisor, ni emulación, ni una imagen de kernel separada. Cada contenedor LXC tiene su propio sistema de archivos, espacio de nombres de red y espacio de procesos, pero las llamadas al sistema van directo al kernel del host de Proxmox.
Eso hace que los contenedores LXC sean extremadamente livianos. Un LXC Debian 12 recién creado usa unos 30-50 MB de RAM, mientras que una VM completa normalmente necesita al menos 512 MB solo para arrancar. Para servicios simples como un resolvedor DNS (Pi-hole), un proxy inverso (Nginx Proxy Manager) o un agente de monitoreo, LXC es increíblemente eficiente.
La trampa: los contenedores LXC dependen del kernel del host. No puedes correr un contenedor Windows, no puedes usar módulos de kernel que no estén cargados en el host, y correr Docker dentro de un contenedor LXC requiere configuración extra (más sobre esto abajo).
Qué es Docker en el contexto de Proxmox
Docker es un runtime de contenedores de aplicaciones. En un homelab con Proxmox, normalmente se usa de una de estas dos formas:
- Dentro de una VM: levantas una VM Debian/Ubuntu, instalas Docker y corres tus contenedores ahí. Limpio, totalmente aislado y funciona igual que Docker en cualquier otra máquina Linux.
- Dentro de un contenedor LXC: corres Docker dentro de un LXC de Proxmox haciéndolo privilegiado (o usando fuse-overlayfs en uno sin privilegios). Más eficiente que una VM completa, pero con advertencias de seguridad y soporte de drivers.
La ventaja de Docker es su ecosistema enorme. Docker Hub tiene imágenes listas para casi cualquier app autoalojada, y Docker Compose te permite declarar stacks de varios servicios en un solo archivo YAML. Si quieres correr Immich (que tiene 5 servicios separados), Docker Compose es la opción sensata.
La matriz de decisión
Este es el criterio que uso para decidir qué enfoque tomar con un servicio nuevo:
Usa LXC cuando:
- El servicio tiene un paquete nativo de Linux (instalable con apt/pacman): Pi-hole, Nginx Proxy Manager, Vaultwarden con el binario oficial, Home Assistant OS (como VM, aunque HA Supervised en un LXC también funciona)
- Necesitas la máxima densidad: LXC es la forma más eficiente de correr muchos servicios pequeños con poca RAM. Subir a 32 GB de DDR4 SODIMM (~$59) en un mini PC te permite correr 15-20 contenedores LXC con comodidad
- El servicio no tiene dependencias complejas de varios contenedores
- Quieres que el respaldo nativo de Proxmox (vzdump) capture todo el servicio de forma limpia
Usa Docker (en una VM) cuando:
- La app se distribuye principalmente como imagen de Docker (Immich, Paperless-ngx, Authentik)
- El servicio requiere un stack de varios contenedores con Docker Compose
- Necesitas aislamiento estricto: una VM tiene un límite de kernel real entre ella y el host
- El servicio necesita passthrough de GPU (transcodificación en Plex, Ollama con GPU): puedes pasar una GPU a una VM y dejar que Docker la use
- Corres cargas no confiables o expuestas a internet
Usa Docker dentro de LXC cuando:
- Quieres el ecosistema de Docker sin la sobrecarga de una VM
- Te sientes cómodo con los pasos de configuración extra y las concesiones de seguridad
- Tu mini PC tiene 16 GB de RAM o menos y cada MB cuenta
Un servicio en LXC (ejemplo práctico: Vaultwarden)
Veamos cómo desplegar Vaultwarden (un gestor de contraseñas compatible con Bitwarden) como contenedor LXC en Proxmox.
Primero crea el contenedor desde la interfaz web de Proxmox o la CLI. Para servicios comunes es muy práctico el proyecto Proxmox Helper Scripts (los scripts de tteck), pero este es el enfoque manual:
# On the Proxmox host
pct create 200 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
--hostname vaultwarden \
--cores 1 \
--memory 256 \
--rootfs local-lvm:8 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1 \
--start 1
pct exec 200 -- bash -c "apt update && apt install -y curl"
Luego, dentro del contenedor, instala Vaultwarden desde el binario oficial:
pct enter 200
# Create a service user
useradd -m -s /bin/bash vaultwarden
# Download the latest binary
cd /opt
curl -L https://github.com/dani-garcia/vaultwarden/releases/latest/download/vaultwarden-$(uname -m)-unknown-linux-musl.tar.gz | tar xz
chmod +x vaultwarden
# Create data directory
mkdir -p /opt/vaultwarden-data
# Create a systemd service
cat > /etc/systemd/system/vaultwarden.service << 'EOF'
[Unit]
Description=Vaultwarden Server
After=network.target
[Service]
User=vaultwarden
WorkingDirectory=/opt
Environment=DATA_FOLDER=/opt/vaultwarden-data
Environment=DOMAIN=https://vault.yourdomain.com
Environment=WEBSOCKET_ENABLED=true
ExecStart=/opt/vaultwarden
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now vaultwarden
Con esta configuración, Vaultwarden corre con 64-80 MB de RAM. En una VM necesitarías al menos 256-512 MB solo para el sistema operativo, además de eso.
Docker en una VM de Proxmox
Para un stack de varios contenedores, una VM dedicada a Docker es el enfoque más limpio. Esta es una VM Debian 12 mínima con Docker:
# Inside your Debian 12 VM
apt update && apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| tee /etc/apt/sources.list.d/docker.list
apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Luego despliega un stack como Immich con un solo archivo compose:
# /opt/immich/docker-compose.yml
services:
immich-server:
image: ghcr.io/immich-app/immich-server:release
volumes:
- /mnt/photos:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file: .env
ports:
- "2283:3001"
depends_on:
- redis
- database
restart: always
redis:
image: docker.io/redis:6.2-alpine
restart: always
database:
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0
env_file: .env
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
volumes:
pgdata:
cd /opt/immich && docker compose up -d
Docker dentro de un contenedor LXC
Si quieres el ecosistema de Docker sin una VM completa, puedes correr Docker dentro de un LXC privilegiado. Es un punto medio: más eficiente que una VM, pero menos aislado.
En Proxmox, edita el archivo de configuración del LXC:
# On the Proxmox host, edit /etc/pve/lxc/101.conf (replace 101 with your container ID)
# Add these lines:
features: keyctl=1,nesting=1
lxc.apparmor.profile: unconfined
lxc.cap.drop:
O, para un contenedor sin privilegios usando fuse-overlayfs (más seguro pero más complejo):
# Inside the LXC container
apt install -y fuse-overlayfs
# Edit /etc/docker/daemon.json
cat > /etc/docker/daemon.json << 'EOF'
{
"storage-driver": "fuse-overlayfs"
}
EOF
systemctl restart docker
El enfoque con fuse-overlayfs te permite mantener el contenedor sin privilegios y aun así correr Docker. El rendimiento es un poco menor que con overlay2 nativo, pero en cargas típicas de homelab no lo vas a notar.
Consideraciones de almacenamiento
Un factor que muchos pasan por alto: el rendimiento del almacenamiento. Tanto los contenedores LXC como las VMs con Docker se benefician muchísimo de un NVMe rápido. Correr muchos contenedores en un disco mecánico genera cuellos de botella de E/S muy rápido. Un SSD NVMe WD Black SN850X de 2 TB (~$129) como almacén de datos de Proxmox cambia la experiencia por completo: los arranques de contenedores y los snapshots que en un HDD tardan decenas de segundos pasan a tomar apenas unos segundos.
Para la red entre contenedores y el host, agregar un adaptador Ethernet USB TP-Link de 2.5G (~$22) a tu mini PC te da ancho de banda suficiente para mover respaldos y archivos grandes sin saturar el enlace que usan tus servicios.
Respaldos: LXC lleva ventaja
La herramienta de respaldo integrada de Proxmox (vzdump) funciona de forma nativa con contenedores LXC. Puedes hacer un snapshot y restaurar un LXC completo (con todos sus servicios y datos) desde la interfaz web de Proxmox en segundos. Programarlo en Datacenter → Backup toma dos minutos.
Con las VMs de Docker tienes dos opciones: respaldar la VM completa (funciona, pero genera archivos de respaldo grandes) o montar tus volúmenes de Docker en una ruta de almacenamiento dedicada y respaldarla aparte con algo como restic o borgbackup. El enfoque con LXC es más simple y ocupa menos espacio en la mayoría de los casos.
Rendimiento en la realidad
En la práctica, la diferencia de rendimiento entre LXC y una VM con Docker para servicios típicos de homelab (interfaces web, bases de datos, servidores multimedia) es insignificante. Ambos se sienten rápidos en hardware moderno. Las diferencias que importan son:
- Tiempo de arranque: los contenedores LXC arrancan en menos de 1 segundo. Las VMs tardan 10-30 segundos.
- Uso de RAM: los contenedores LXC usan solo lo que necesita el servicio. Las VMs necesitan como mínimo 256-512 MB para el sistema operativo.
- Densidad: en un sistema de 16 GB puedes correr cómodamente más de 20 contenedores LXC. Correr 20 VMs agotaría la RAM rápidamente.
- Aislamiento: las VMs tienen un límite de kernel duro. Un contenedor Docker comprometido dentro de una VM no puede afectar al host de Proxmox. Un contenedor LXC privilegiado comprometido, potencialmente sí.
Una organización de ejemplo
Como referencia, así se pueden repartir los servicios entre ambos enfoques en un nodo de Proxmox:
- Contenedores LXC: Pi-hole, Nginx Proxy Manager, Vaultwarden, Uptime Kuma, Netdata, nodo de salida de Tailscale, Headscale
- VM con Docker: Immich, Paperless-ngx, Authentik, Portainer (para administrar los demás contenedores Docker)
- Docker en LXC: un stack de n8n + Ollama (donde se necesita Docker Compose pero quieres mantener bajo el uso de RAM)
Este enfoque híbrido te da lo mejor de los dos mundos: contenedores LXC eficientes y casi nativos para los servicios simples, y el ecosistema de Docker para las apps complejas de varios servicios.
En resumen
No lo trates como una elección binaria. Usa LXC cuando un servicio tiene un camino de instalación nativo y limpio en Linux y quieres la máxima eficiencia. Usa Docker (en una VM) cuando la app es nativa de Docker, tiene varios contenedores o necesita aislamiento estricto. Usa Docker dentro de LXC cuando tienes poca RAM y estás dispuesto a hacer algo de configuración extra.
La fortaleza de Proxmox es justamente que maneja los tres enfoques de forma nativa: no estás atado a un solo paradigma. Empieza con LXC para los servicios simples, agrega una VM con Docker para los stacks complejos y deja que cada carga decida la herramienta.
¿Quieres algo así para tu negocio?
Instalo infraestructura privada y autoalojada en Proxmox: IA, automatización y herramientas internas en hardware que es tuyo, documentado y entregado. Ver el stack de IA privada →
¿No sabes qué necesitas? Agenda una llamada gratis.