Perché Docker e non Home Assistant OS
Home Assistant si può installare in più modi: Home Assistant OS (un sistema operativo dedicato, pensato per un Raspberry Pi o una macchina virtuale intera), il supervised install, oppure il container Docker, che è quello che uso su un PC Windows che resta acceso 24 ore su 24 e fa anche altro. Il vantaggio è che Home Assistant vive isolato in un suo contenitore, accanto ad altri servizi (in questo caso gireranno anche loro in container separati), senza bisogno di una macchina virtuale intera o di un secondo PC dedicato. Il compromesso: niente Supervisor e niente store degli add-on integrato come su Home Assistant OS. Le integrazioni si installano comunque tutte, HACS compreso; cambiano solo il modo di aggiornare il sistema e la gestione dei backup, che diventano compiti tuoi invece che del Supervisor.
Passo 1 — Attiva WSL2
Docker Desktop su Windows si appoggia a WSL2 (Windows Subsystem for Linux) come motore. Se non l'hai mai installato, apri PowerShell come amministratore e lancia:
# Abilita WSL2 e installa una distribuzione Linux di base (serve solo come motore per Docker)
wsl --install
# Controlla la versione: deve rispondere con un numero, non con un errore
wsl --version
Se il comando chiede un riavvio, riavvia il PC prima di proseguire. Se rispondeva già con un numero di versione, WSL2 è già pronto e puoi saltare il riavvio.
Passo 2 — Installa Docker Desktop da PowerShell
Con winget (incluso in Windows 10/11 aggiornati) non serve scaricare nulla a mano dal sito:
winget install --id Docker.DockerDesktop -e --accept-package-agreements --accept-source-agreements
Al termine, avvia Docker Desktop una prima volta dal menu Start: accetta i termini di licenza e, se te lo chiede, lascia che finisca la configurazione del motore WSL2. Il login con un account Docker Hub è facoltativo per quello che serve a questa guida: puoi chiuderlo con "Skip" se non ne hai uno.
Passo 3 — Verifica che Docker sia pronto
Da PowerShell (non serve più l'amministratore da qui in poi):
docker version
docker info
# Se hai appena avviato Docker Desktop, il motore puo' metterci un po': questo ciclo aspetta
# fino a 2 minuti e mezzo prima di arrendersi
$ok = $false
for ($i = 0; $i -lt 30 -and -not $ok; $i++) {
Start-Sleep 5
docker info *> $null
if ($LASTEXITCODE -eq 0) { $ok = $true }
}
if ($ok) { Write-Host 'Docker pronto.' -ForegroundColor Green }
else { throw 'Docker non risponde: apri Docker Desktop dal menu Start e controlla che l''icona nella barra sia verde.' }
Se docker info risponde con dati (versione, numero di container, ecc.) invece che con un errore, sei pronto per il passo successivo.
Passo 4 — Crea la cartella di configurazione
La configurazione di Home Assistant (le sue entità, automazioni, cronologia) vive fuori dal container, in una cartella su Windows: così sopravvive a un aggiornamento o a una ricreazione del container.
$Dir = 'C:dockerhomeassistant'
New-Item -ItemType Directory -Force "$Dirconfig" | Out-Null
Write-Host "Cartella pronta: $Dirconfig"
Passo 5 — Scrivi il docker-compose.yml
Uso sempre Docker Compose invece di un docker run lunghissimo da ricordare: il file resta lì, documenta da solo cosa gira e con quali impostazioni.
$compose = @'
name: homeassistant
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
ports:
- "8123:8123"
volumes:
- ./config:/config
environment:
TZ: Europe/Rome
'@
$utf8 = New-Object System.Text.UTF8Encoding($false)
[IO.File]::WriteAllText("$Dirdocker-compose.yml", $compose, $utf8)
Write-Host "Scritto: $Dirdocker-compose.yml"
Uso la rete bridge di Docker con la porta 8123 pubblicata (ports: - "8123:8123") invece di network_mode: host: su Docker Desktop per Windows il networking host non si comporta come su Linux, mentre la porta pubblicata funziona in modo prevedibile sempre. Il prezzo da pagare è che la scoperta automatica dei dispositivi in rete (mDNS/SSDP, quella che su alcune integrazioni fa comparire da sola un dispositivo appena acceso) qui non funziona: per quelle integrazioni inserisci l'indirizzo IP a mano, una tantum, quando le aggiungi.
Passo 6 — Avvia il container
docker compose -f "$Dirdocker-compose.yml" up -d
if ($LASTEXITCODE -ne 0) { throw 'docker compose non e'' riuscito: controlla l''errore qui sopra.' }
Passo 7 — Verifica che sia tutto ok
Tre controlli, in ordine: il container esiste ed è "Up", i log non mostrano errori bloccanti, e l'interfaccia risponde davvero sulla porta.
# 1. Il container e' in esecuzione?
docker ps --filter name=homeassistant
# 2. Gli ultimi log (al primo avvio Home Assistant impiega circa 1-2 minuti a preparare il database)
docker logs --tail 50 homeassistant
# 3. L'interfaccia risponde? Ciclo di attesa fino a 2 minuti
$up = $false
for ($i = 0; $i -lt 24 -and -not $up; $i++) {
Start-Sleep 5
try { Invoke-WebRequest 'http://localhost:8123' -UseBasicParsing -TimeoutSec 5 | Out-Null; $up = $true }
catch { if ($_.Exception.Response) { $up = $true } }
}
if ($up) { Write-Host 'Home Assistant e'' su: apri http://localhost:8123' -ForegroundColor Green }
else { Write-Warning 'Non risponde ancora dopo 2 minuti: guarda "docker logs homeassistant" per capire a che punto si e'' fermato.' }
Passo 8 — Completa l'installazione guidata
Apri http://localhost:8123 nel browser: Home Assistant ti guida nella creazione dell'account amministratore, del nome della casa, della posizione (serve per alba/tramonto e meteo) e ti propone di rilevare da solo i dispositivi già presenti in rete (quelli che il networking bridge riesce comunque a vedere, es. dispositivi con IP statico già noto). Da qui in poi la configurazione si fa tutta dall'interfaccia web.
Apri l'accesso dalla rete locale (opzionale)
Se vuoi raggiungere Home Assistant anche da altri dispositivi in casa (telefono, tablet) e non solo dal PC dove gira, apri la porta sul firewall di Windows per la sola rete privata:
New-NetFirewallRule -DisplayName 'Home Assistant 8123' -Direction Inbound -Protocol TCP `
-LocalPort 8123 -Action Allow -Profile Private | Out-Null
$ip = (Get-NetIPAddress -AddressFamily IPv4 |
Where-Object { $_.IPAddress -notmatch '^(127|169.254)' -and $_.PrefixOrigin -ne 'WellKnown' } |
Select-Object -First 1).IPAddress
Write-Host "Raggiungibile in LAN su: http://$ip`:8123"