Running Home Assistant on Windows in Docker
I wanted to move HA to my home server, I can run Hyper-V images as needed but most service I run these days are in Docker, so looked up how to do this for Home Assistant.
Introduction
This was originally taken from [Guide] Hass.IO on Windows 10 WSL2 (No more VMs!) and updated as needed for how I run it on Windows.
Basically this is HASS.IO running on Docker in Windows 10 WSL2
Setting up WSL 2
Install WSL (Don’t install a linux distro yet): Open PowerShell as Administrator and run
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
Restart your computer when prompted.
Enable WSL2 Open PowerShell as Administrator and run:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Restart computer to apply changes
Open PowerShell as Administrator and the following command, leave it open after doing so.
wsl --set-default-version 2
Open the Microsoft Store and install Ubuntu, launch it and let it install, it will prompt to set a username and password.
Verify ubuntu is using WSL2 via the Powershell from before using
wsl --list --verbose
orwsl -l -v
Start the WSL shell by running
wsl
in the powershell window.Run
sudo apt-get update
in Ubuntu
Prepare for Home Assistant Install
If you want to upgrade this is helpful How to Upgrade Ubuntu 18.04 LTS to 20.04 LTS on WSL (Windows 10)
For Ubuntu 18.04:
wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
For Ubuntu 19.04:
wget -q https://packages.microsoft.com/config/ubuntu/19.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
For Ubuntu 20.04 (This appears to be the version that is installed from the store currently for “Ubuntu”)
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
The rest should be the same for all of them
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1
curl -s https://packagecloud.io/install/repositories/arkane-systems/wsl-translinux/script.deb.sh | sudo bash
sudo apt install systemd-genie
System restart might be needed, try running genie -s
in ubuntu terminal, if you get an error run genie -c bash
Install Home Assistant
References
- install dependencies and HASS.io
- Docker CE instructions here: https://docs.docker.com/install/linux/docker-ce/ubuntu/
Install the dependencies below first.
sudo apt-get install \
bash \
jq \
curl \
avahi-daemon \
dbus \
apparmor-utils \
network-manager
Run as root (sudo su)
curl -Lo installer.sh https://raw.githubusercontent.com/home-assistant/supervised-installer/master/installer.sh
bash installer.sh --machine qemux86-64
Within a few minutes you’ll be able to access HASS.IO on localhost:8123
- Networking & Starting with Windows
Unfortunately, WSL2 does not yet support bridged networking
So in order to be able to access HASS from outside the local machine we’ll need to run this workaround script at startup, it will also run HASS with the “genie -i” command.
Save this script somewhere on your PC with a .ps1 ending, note that you can add/remove/edit the ports you want forwarded from WSL
bash.exe -c "genie -i"
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
# [Ports]
# All the ports you want to forward separated by coma
$ports=@(80,443,8123,1880,1883,1884,8883,8884);
# [Static ip]
# You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
# Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
# adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}
Open Task Scheduler and add click “Create Task” Under General - “Check run whether user is logged in or not” and “Run with the highest privileges” Under triggers click New, Begin the task at logon of any user Under Actions click New, Select Start a program and type in program/script ‘Powershell.exe’ in arguments type ‘-ExecutionPolicy Bypass c:\Users\User\hass.ps1’ (Change the path to your saved script file)
(Optional: Under settings you can check “if the task fails, restart every X minutes” if you’re having issues)
hit OK.
Power options - Set sleep to Never
If you want your user to autologin -> open start -> Run, type ‘control userpasswords2’ and uncheck “Users must enter a name and password to use this computer"Within a few minutes you’ll be able to access HASS.IO on localhost:8123
Networking & Starting with Windows
Unfortunately, WSL2 does not yet support bridged networking
So in order to be able to access HASS from outside the local machine we’ll need to run this workaround script at startup, it will also run HASS with the “genie -i” command.
Save this script somewhere on your PC with a .ps1 ending, note that you can add/remove/edit the ports you want forwarded from WSL
bash.exe -c "genie -i"
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
# [Ports]
# All the ports you want to forward separated by coma
$ports=@(80,443,8123,1880,1883,1884,8883,8884);
# [Static ip]
# You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
# Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
# adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}
Open Task Scheduler and add click “Create Task” Under General - “Check run whether user is logged in or not” and “Run with the highest privileges” Under triggers click New, Begin the task at logon of any user Under Actions click New, Select Start a program and type in program/script ‘Powershell.exe’ in arguments type ‘-ExecutionPolicy Bypass c:\Users\User\hass.ps1’ (Change the path to your saved script file)
(Optional: Under settings you can check “if the task fails, restart every X minutes” if you’re having issues)
hit OK.
- Power options - Set sleep to Never
- If you want your user to autologin -> open start -> Run, type ‘control userpasswords2’ and uncheck “Users must enter a name and password to use this computer”