I’ve managed to move my current Home Assistant install from a python virtual environment to Docker. This will allow me to upgrade the host operating system or move to a new computer without too much difficulty. The most difficult thing to get working was the networking and it took me a while to work out which containers needed to be on the host network and which could be on the default docker network.
My Docker stack has the following components:
- Mosquitto
- Zigbee2MQTT
- Home Assistant
- NodeRed
- ESPhome
- Lets-encrypt
- My own personal power monitor Perl script
- Watchtower
- MySQL
- phpMyAdmin
Eventually I’ll move my Plex install into the same environment but I’m waiting for me new 8Tb hard drive.
The docker-compose file looks like this:
version: '3.5'
services:
mosquitto:
container_name: mqtt
hostname: mqtt
image: eclipse-mosquitto
labels:
- com.centurylinklabs.watchtower.enable=true
restart: always
ports:
- 1883:1883
- 8883:8883
- 9001:9001
volumes:
- /mnt/data/docker/mosquitto/config:/mosquitto/config
- /mnt/data/docker/mosquitto/data:/mosquitto/data
- /mnt/data/docker/mosquitto/log:/mosquitto/log
- /etc/localtime:/etc/localtime:ro
zigbee2mqtt:
container_name: zigbee2mqtt
hostname: zigbee2mqtt
image: koenkk/zigbee2mqtt:latest
volumes:
- /mnt/data/docker/zigbee2mqtt:/app/data
- /run/udev:/run/udev:ro
- /etc/localtime:/etc/localtime:ro
devices:
- /dev/ttyACM0:/dev/ttyACM0
depends_on:
- mosquitto
restart: always
privileged: true
environment:
- TZ=Australia/Hobart
homeassistant:
container_name: homeassistant
hostname: homeassistant
image: homeassistant/home-assistant
volumes:
- /mnt/data/docker/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
depends_on:
- mosquitto
restart: always
network_mode: host
nodered:
container_name: nodered
hostname: nodered
labels:
- com.centurylinklabs.watchtower.enable=true
network_mode: host
image: nodered/node-red-docker:latest
ports:
- 1880:1880
volumes:
- /mnt/data/docker/node-red:/data
- /etc/localtime:/etc/localtime:ro
depends_on:
- mosquitto
- homeassistant
restart: always
environment:
- TZ=Australia/Hobart
esphome:
container_name: esphome
hostname: esphome
image: esphome/esphome
labels:
- com.centurylinklabs.watchtower.enable=true
volumes:
- /mnt/data/docker/esphome:/config
- /etc/localtime:/etc/localtime:ro
restart: always
network_mode: host
lets-encrypt:
container_name: letsencrypt
hostname: letsencrypt
image: linuxserver/letsencrypt
labels:
- com.centurylinklabs.watchtower.enable=true
restart: always
volumes:
- /mnt/data/docker/homeassistant/letsencrypt:/config
- /etc/localtime:/etc/localtime:ro
ports:
- 433:433
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- EMAIL=chris.jennings@riscy.biz
- URL=#####
- VALIDATION=duckdns
- TZ=Australia/Hobart
- DUCKDNSTOKEN=#######
powerlog:
container_name: powerlog
hostname: powerlog
image: powerlog
restart: always
privileged: true
volumes:
- /mnt/data/docker/powerlog:/usr/src/myapp
- /run/udev:/run/udev:ro
- /etc/localtime:/etc/localtime:ro
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
links:
- mysql:mysql
command: perl /usr/src/myapp/powerlog.pl
watchtower:
container_name: watchtower
image: containrrr/watchtower
command: --cleanup --label-enable
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
mysql:
container_name: mysql
hostname: mysql
image: mysql
ports:
- 3306:3306
restart: always
volumes:
- /mnt/data/docker/mysql:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
phpmyadmin:
container_name: phpmyadmin
hostname: phpmyadmin
image: phpmyadmin/phpmyadmin
ports:
- 8080:80
restart: always
volumes:
- /mnt/data/docker/phpmyadmin:/sessions
- /etc/localtime:/etc/localtime:ro
links:
- mysql:db
I have all the docker mounted volumes in a folder /mnt/data/docker. To migrate MySQL I had to export the data and then import it into the new docker container. Copying the files over didn’t work, maybe it was because the MySQL version was incompatible. Best practice usually requires a mysqldump and import instead of just copying the MySQL files over.
Ensure that host names are set correctly so that containers can talk to each other. I also mounted /etc/localtime on each container to ensure the time is correct. Initially my Perl script was time stamping incorrectly because I didn’t map the time through.