Home Assistant in Docker #3: docker-compose.yml for Home Assistant and MariaDB explained
In the current post series, I’m describing the path I took from a regular Home Assistant setup on Home Assistant Blue to a home server with Docker and various software. Assuming we already have ODROID-N2+ with Debian Buster and Docker setup, our next step would be bringing Home Assistant with MariaDB to life.
Previous posts in series:
- Debian Buster on ODROID-N2+ aka Home Assistant Blue
- Installing Docker on ODROID-N2+ with Debian Buster
Docker Compose allows us to define and run multi-image applications with one simple YAML file and one command. Home Assistant is sure could be a multi-image application, because at least we need a good solution for history and stats. Later on, we will add ESPHome, Zigbee2MQTT, and other services, but in today’s post let’s focus on a Home Assistant itself.
I don’t want to drop my docker-compose.yml
here and mind my own business. There are a lot of examples around the Internet, but most of them have questionable configuration entries. I want to explain, why and when you need to use one or another docker settings.
Host network mode for example. Official Home Assistant documentation suggests using network_mode: host
not mentioning, that it would be a good practice only when your Home Assistant is the only container in your smart home setup. When we have several containers that should communicate with each other, we sure need to use network_mode: bridge
. First of all, it would follow official docker docs. Second, it will allow us to use container names instead of IP addresses (that could be changed) when integrating our additional services into HA.
Also, why Home Assistant needs a privileged mode? Exposing your operating system to a service that could potentially be accessed from the outside of your router sounds like a very bad idea. Not gonna lie, this would be the easiest way to start using Home Assistant in a Docker: host network mode and privileged execution. But you can avoid potential risks and issues in the future just by understanding slightly more complex configuration options.
The most comfortable way to edit files, execute commands, and do any other things with your headless (which means a computer without a monitor) server is to use Visual Studio Code with the “Remote – SSH” plugin.
docker-compose.yml
Now it is time to drop my docker-compose.yml
and describe some more things on a working example:
version: "3"
name: homeassistant_stack
services:
mariadb:
image: mariadb
container_name: mariadb
restart: unless-stopped
hostname: mariadb
ports:
- 3306:3306
environment:
MARIADB_ROOT_PASSWORD: *******
MARIADB_DATABASE: homeassistant
MARIADB_USER: my_own_house
MARIADB_PASSWORD: *******
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:latest"
volumes:
- /root/homeassistant/config:/config
- /root/homeassistant/share:/share
environment:
- TZ=Europe/Kyiv
ports:
- 8123:8123
devices:
- /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0:/dev/ttyACM1
depends_on:
- "mariadb"
restart: unless-stopped
As I’m using my server as a root user, my home directory is /root
. I’ve placed docker-compose.yml
in /root
and have a separate folder for each smart home stack service. I’ve created the/root/homeassistant/config
directory for Home Assistant configuration, and /root/homeassistant/share
for the HA share folder. “share” folder is not necessary. I created it only because I had an integration that stores a file in the “share” folder. You can create “media” and any other folders the same way if you need it.
So, obviously, these lines in homeassistant
service are for exposing host folders to a Home Assistant container:
volumes:
- /root/homeassistant/config:/config
- /root/homeassistant/share:/share
Let’s get back to the mariadb
service for now. The ports
allow us to expose network ports for inbound connections. 3306 is a standard MariaDB port. HA will use it for connection.
MARIADB_ROOT_PASSWORD
is a root password for your MariaDB installation. MARIADB_DATABASE
variable would force MariaDB to create a database with a given name upon a first start, assigning MARIADB_USER
with MARIADB_PASSWORD
to it. You will need this data for the Home Assistant configuration later.
Going back to the homeassistant
service, let us look to other options:
environment:
- TZ=Europe/Kyiv
You should replace “Europe/Kyiv” with your timezone name taken from the “TZ database name” column in the table here.
image: "ghcr.io/home-assistant/home-assistant:latest"
This will pull the latest stable Home Assistant version from packages on GitHub but only when you’ll tell Docker Compose to do so. Stopping and starting the container will not pull any images.
To get more control over Home Assistant versions you can replace latest
with a given package tag found here. For example:
image: "ghcr.io/home-assistant/home-assistant:2022.12.7"
Now you’ll be sure that Home Assistant will not be updated until you update your docker-compose.yml
.
ports:
- 8123:8123
This is the only port you need to expose to make Home Assistant work even through Nabu Casa Cloud.
devices:
- /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0:/dev/ttyACM1
This is how you allow a given hardware from your host machine to be used in Home Assistant. /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
– is a GSM modem, connected to my host machine. /dev/ttyACM1
– is a path to a device I’m using in Home Assistant when adding GMS modem integration.
depends_on:
- "mariadb"
These lines will tell Docker that when the Home Assistant container is starting, it should wait till MariaDB will be up first. Otherwise Recorder component in Home Assistant will fail to start and you’ll get Home Assistant without entities history.
First start
Now it is time to fire things up with:
docker compose up -d
You should execute this command in the same folder where your docker-compose.yml
is placed.
This will download all the necessary data to start your Home Assistant. Once done, you should be able to navigate to your Home Assistant frontend using your server’s IP address and port 8123. For example “http://192.168.90.23:8123” from inside your local network.
HA config
Now we need to configure the recorder
component in the newly created configuration.yaml
file. In my case, it is created under /root/homeassistant/config
:
recorder:
db_url: mysql://my_own_house:*******@mariadb/homeassistant?charset=utf8mb4
auto_purge: true
purge_keep_days: 10
The database URL is consist of mysql://MARIADB_USER:MARIADB_PASSWORD@mariadb/MARIADB_DATABASE?charset=utf8mb4
“mariadb” in the URL is the name of our service from docker-compose.yml
.
Stopping, starting and restarting
Now we need to restart Home Assistant for changes to apply. We can easily do this with:
docker compose restart homeassistant
Sure you can do the same from Home Assistant UI as usual.
While you have several services defined in your docker-compose.yml
docker compose restart
without any additional parameters will restart all services. Also, you can just stop
any container or start
it:
docker compose start mariadb
Or stop it all:
docker compose stop
Updating
Not sure why you’ll want to update your MariaDB container while it works, but updating Home Assistant is important.
If you are using latest
tag for your homeassistant
service image:
image: "ghcr.io/home-assistant/home-assistant:latest"
to update it to a latest stable version you’ll need to:
docker compose pull homeassistant
and then
docker compose up -d homeassistant
That’s it.
Don’t forget to change the image tag if you are not using latest
.
Next posts in series: