Esta guía describe cómo crear y gestionar VMs de Home Assistant OS en Proxmox VE, incluyendo el script de creación automática y la gestión de red.
Internet (GCP)
│
ens4 (IP dinámica GCP)
│
Proxmox Host — NAT/MASQUERADE
├── vmbr0 (192.168.100.1/24) — red interna Proxmox
│ │
│ OpenWRT VM (VMID 200)
│ ├── eth0 → WAN → 192.168.100.2/24
│ └── br-lan → LAN → 10.10.10.1/24
│
└── vmbr1 (10.10.10.0/24) — red de clientes
│
VMs HAOS → IP 10.10.10.<VMID>
Regla de IPs: cada VM recibe la IP 10.10.10.<VMID>. El VMID debe estar entre 1 y 254.
vmbr0 creado como Linux bridge sin puertos físicosvmbr1 creado como Linux bridge sin IP en el host/var/lib/vz/snippets/hookscript.shssh-copy-id root@192.168.100.2curl, jq, wget, xzEste script automatiza la creación de VMs de Home Assistant OS en Proxmox VE. Solicita versión, almacenamiento, VMID y nombre, y crea la VM con configuración óptima.
cat > /usr/local/bin/HA-vm.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
log() { echo "[INFO] $*"; }
err() { echo "[ERROR] $*" >&2; exit 1; }
warn() { echo "[WARN] $*"; }
[[ "$EUID" -ne 0 ]] && err "Por favor, ejecuta como root"
for cmd in curl jq wget xz pvesm qm; do
command -v "$cmd" >/dev/null 2>&1 || err "Dependencia no encontrada: $cmd"
done
# 1. Selección de versión
log "Consultando versiones disponibles de HAOS..."
VERSIONS=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases \
| jq -r '.[].tag_name' | head -n 10)
[[ -z "$VERSIONS" ]] && err "No se pudieron obtener versiones."
echo ""
echo "Selecciona la versión de HAOS:"
select VER in $VERSIONS; do
[[ -n "$VER" ]] && break
warn "Opción no válida."
done
# 2. Selección de almacenamiento
echo ""
echo "Selecciona el almacenamiento:"
mapfile -t STORAGES < <(pvesm status | awk 'NR>1 {print $1}')
select STORAGE in "${STORAGES[@]}"; do
[[ -n "$STORAGE" ]] && break
warn "Opción no válida."
done
# 3. VMID con validación
echo ""
while true; do
read -rp "VMID (número entre 1 y 254): " VMID
[[ "$VMID" =~ ^[0-9]+$ ]] || { warn "VMID debe ser numérico."; continue; }
[[ "$VMID" -ge 1 && "$VMID" -le 254 ]] || { warn "VMID debe estar entre 1 y 254."; continue; }
if qm status "$VMID" &>/dev/null; then
warn "El VMID $VMID ya existe. Elige otro."
else
break
fi
done
read -rp "Nombre de la VM: " NAME
[[ -z "$NAME" ]] && err "El nombre no puede estar vacío."
# 4. Descarga de imagen
IMG_FILE="/tmp/haos_${VER}.qcow2"
IMG_URL="https://github.com/home-assistant/operating-system/releases/download/${VER}/haos_ova-${VER}.qcow2.xz"
trap 'rm -f "${IMG_FILE}.xz" "$IMG_FILE"' EXIT
log "Descargando HAOS ${VER}..."
wget -q --show-progress -O "${IMG_FILE}.xz" "$IMG_URL" \
|| err "Fallo en la descarga."
log "Descomprimiendo imagen..."
xz -d "${IMG_FILE}.xz"
[[ -f "$IMG_FILE" ]] || err "La imagen no se descomprimió correctamente."
# 5. Crear VM
log "Creando VM $VMID ($NAME)..."
qm create "$VMID" \
--name "$NAME" \
--memory 2048 \
--cores 2 \
--net0 virtio,bridge=vmbr1 \
--scsihw virtio-scsi-pci \
--bios ovmf \
--machine q35 \
--serial0 socket \
--vga serial0
# 6. Disco EFI sin Secure Boot
log "Creando disco EFI (Secure Boot desactivado)..."
qm set "$VMID" --efidisk0 "${STORAGE}:4,efitype=4m,pre-enrolled-keys=0"
# 7. Importar disco principal
log "Importando disco HAOS..."
qm importdisk "$VMID" "$IMG_FILE" "$STORAGE"
# 8. Buscar y adjuntar disco importado
DISK_NAME=$(pvesm list "$STORAGE" --vmid "$VMID" \
| grep "vm-${VMID}-disk-" \
| grep -v "efidisk" \
| awk '{print $1}' \
| cut -d':' -f2)
[[ -z "$DISK_NAME" ]] && err "No se encontró el disco importado."
log "Adjuntando disco: $DISK_NAME"
qm set "$VMID" --scsi0 "${STORAGE}:${DISK_NAME},format=raw,discard=on,ssd=1"
# 9. Configurar arranque
qm set "$VMID" --boot order=scsi0
# 10. Asignar hookscript
HOOKSCRIPT_PATH="/var/lib/vz/snippets/hookscript.sh"
if [[ -f "$HOOKSCRIPT_PATH" ]]; then
qm set "$VMID" --hookscript local:snippets/hookscript.sh
log "Hookscript asignado."
else
warn "Hookscript no encontrado en $HOOKSCRIPT_PATH."
fi
trap - EXIT
rm -f "$IMG_FILE"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ✅ VM creada correctamente"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " VMID : $VMID"
echo " Nombre : $NAME"
echo " Versión HAOS: $VER"
echo " Storage : $STORAGE"
echo " Red : vmbr1"
echo " IP asignada : 10.10.10.${VMID}"
echo " UEFI : OVMF + q35, Secure Boot OFF"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Para arrancar: qm start $VMID"
echo ""
EOF
chmod +x /usr/local/bin/HA-vm.sh
bash /usr/local/bin/HA-vm.sh
El script es interactivo — pidiendo versión, storage, VMID y nombre. Al finalizar la VM está lista para arrancar con qm start <VMID>.
El hookscript se asigna automáticamente al crear la VM. No hace falta asignarlo manualmente salvo en VMs creadas por otros medios.
Si la VM falla al arrancar con BdsDxe: Access Denied, el problema es Secure Boot activo. Solución:
qm set <VMID> --delete efidisk0
qm set <VMID> --efidisk0 <storage>:4,efitype=4m,pre-enrolled-keys=0
Para crear un contenedor Debian desde línea de comandos:
pct create <ID> data:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
--hostname <nombre> \
--cores 1 \
--memory 512 \
--swap 512 \
--rootfs data:20 \
--net0 name=eth0,bridge=vmbr0,ip=192.168.100.X/24,gw=192.168.100.1 \
--net1 name=eth1,bridge=vmbr1,ip=10.10.10.X/24 \
--nameserver 8.8.8.8 \
--unprivileged 1 \
--password <contraseña> \
--start 1
Usar siempre data como almacenamiento, nunca local o local-lvm.
Por defecto Debian 13 no permite login de root por contraseña. Editar /etc/ssh/sshd_config y descomentar o modificar:
PermitRootLogin yes
PasswordAuthentication yes
Reiniciar SSH:
systemctl restart ssh
Ver también: OpenWRT en Proxmox, Configuración de Proxmox