Open goderz opened 4 months ago
Try the following service definition as your starting point:
esphome:
container_name: esphome
image: ghcr.io/esphome/esphome
restart: unless-stopped
environment:
- TZ=${TZ:-Etc/UTC}
- USERNAME=${ESPHOME_USERNAME:?eg echo ESPHOME_USERNAME=test >>~/IOTstack/.env}
- PASSWORD=${ESPHOME_PASSWORD:?eg echo ESPHOME_PASSWORD=ChangeMe >>~/IOTstack/.env}
network_mode: host
x-ports:
- "6052:6052"
x-privileged: true
volumes:
- ./volumes/esphome/config:/config
This is based upon ESPHome documentation with adjustments to conform with the norms for IOTstack.
The significant differences are:
Rather than map /etc/localtime
into the container (which, although common, is a bit of a hack), IOTstack passes TZ into the container. You can initialise to your own time-zone by doing this:
$ echo "TZ=$(cat /etc/timezone)" >>~/IOTstack/.env
This means a single entry in the .env
file passes TZ to all the containers which support TZ (in essence, those that have the tzdata
package installed).
Rather than provide known defaults for the username and password, this structure of those environment variables forces you to initialise the values yourself (in keeping with best practice):
$ echo "ESPHOME_USERNAME=goderz" >>~/IOTstack/.env
$ echo "ESPHOME_PASSWORD=my-super-secure-password" >>~/IOTstack/.env
If you don't, you get a long-winded (and badly laid-out) error message telling you to run those commands.
The x-ports
clause is inactive (any clause starting with x-
is treated as a comment). The reason for including it is to document the fact the ESPhome uses port 6052. This helps avoid allocating that port to another service.
I have disabled the privileged
flag (by prepending x-
). I am always suspicious about any service definition I find on the web which includes this flag. It is rarely needed. What it does is let the container break containerisation. Most containers run as root so using this flag gives the container (and its authors) access to your entire host.
In many cases, this flag seems to be used as a lazy way of providing access to /dev
, completely ignoring the fact that it also provides unrestricted access to the entire host.
If a container needs access to specific devices, those should be mapped in, either using a devices:
clause (providing access to specific devices) or cgroup rules (providing access to a class of devices). For example:
devices:
- "/dev/ttyACM0:/dev/ttyACM0"
device_cgroup_rules:
- "c 188:* rw"
I don't use ESPhome so I don't know what it is doing or how it works, so I can't say whether privileged
is appropriate. I'll leave it to you to sort out whether it is warranted.
By convention, IOTstack containers have persistent stores at:
~/IOTstack/volumes/«containerName»/«path»
My proposed service definition conforms with this by mapping:
volumes:
- ./volumes/esphome/config:/config
Are there any known compatibility issues with ESPHome in the current IOTstack environment?
None that jumped out at me. The above service definition ran first time without incident.
Best practices to avoid port conflicts when adding the ESPHome container?
The network_mode: host
clause means the container binds to the host's ports. On startup, the container writes the following message to its log:
2024-02-17 10:47:45,765 INFO Starting dashboard web server on http://0.0.0.0:6052 and configuration dir /config...
That is what caused me to document port 6052 in the x-ports
clause. Port 6052 is not mentioned in any other IOTstack service definition so it is unlikely to cause a conflict.
The container may be binding to other ports. I was able to connect a browser to port 6052. Clicking the button to add a new device produced:
That implies that ESPhome really wants to connect over HTTPS but whether that implies a different port is something I don't know. That's something you'll have to figure out.
The Dockerfile only declares port 6052 but the lack of a declaration doesn't stop a process running inside a container from binding to other ports.
In general, I default to containers running in non-host mode unless there's a good reason to run in host mode. Running in non-host mode means you can use a ports:
clause for any external port you like and Network Address Translation takes care of the details. You get a lot more flexibility that way.
One good reason to run in host mode is that the container needs to register to receive multicast traffic or snoop on broadcast traffic. Because non-host mode containers connect to an internal (software-emulated) network, traffic to/from that internal network is routed (meaning broadcast packets aren't transported) and Docker doesn't support forwarding multicast traffic to/from internal networks.
If you know that ESPhome needs broadcast/multicast then so be it. But if your reading about ESPhome suggests that it doesn't actually need those capabilities then you can try inverting the arrangement like this:
x-network_mode: host
ports:
- "6052:6052"
Advice on managing ESPHome configurations within Docker?
No. I assume that configurations get written to the internal directory:
/config
which means they will persist to the external directory:
~/IOTstack/volumes/esphome/config
but that is something you should verify. Assuming that's the way it works then backup routines will capture the configurations.
Any specific security considerations with ESPHome?
Other than my reservations about the wisdom (or otherwise) of the privileged
flag, none.
Hope this helps.
If you get it running and can write some documentation for other people to follow then I can help you create a pull request to have this added to IOTstack.
@goderz any feedback ?
Hey @Noschvie
Unfortunately, I must point out that I haven't attempted to run ESPHome in the end. I'm doing all of this strictly as a hobby, and I had to focus on something entirely different at the moment. I'll probably return to IoT-related projects later this year. I apologize for the lack of response.
@goderz that's cool by me
@Noschvie I assume you commented because you're interested in this too. If yes, have you tried it? Does it work? Should it become a Pull Request for being added to IOTstack? Any hints for what should be in documentation to help people get started?
Hello @Paraphraser Phill sorry for the delay. I'm interested, but not a user of ESPHome. Because of an existing integration for HA I think it's not needed to add it to IOTstack.
Hi IOTstack Team,
I've been using IOTstack on my Raspberry Pi and am planning to add ESPHome to my setup for home automation projects. Before I proceed, I wanted to get some insights to ensure a smooth integration.
Here are my main concerns:
Appreciate any guidance you can provide to help me integrate ESPHome effectively.
Also, I'm quite new to Docker, so I'd appreciate any tips on what to consider when adding more containers in the future.
Thanks, Paweł.