New services, cleanup, readme
This commit is contained in:
parent
05c8d61e0a
commit
a0e3ff6375
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
**/*
|
||||
|
||||
!.gitignore
|
||||
!docker-compose.yml
|
||||
!README.md
|
||||
|
||||
!hass
|
||||
!hass/*
|
76
README.md
Normal file
76
README.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Home Assistant docker compose
|
||||
|
||||
This compose sets up Home Assistant and services used by it
|
||||
|
||||
## hass
|
||||
Home assistant container.
|
||||
|
||||
The image is specially built with the following features
|
||||
- Home Assistant doesn't run as root
|
||||
- /config is a volume
|
||||
- /home/hass/.local/lib is a volume to make pip cache persistent between rebuilds
|
||||
- Port 8123 is exposed by default
|
||||
- Added a healthcheck
|
||||
- If the env variable WAITDB_HOST is set Home Assistant doesn't start until the mysql database at that host with username WAITDB_USER and password WAITDB_PASS is available.
|
||||
|
||||
Available on all networks.
|
||||
Make sure to select all network adapters as active under Configuration->General->Network so `discovery` works.
|
||||
|
||||
To update:
|
||||
|
||||
```bash
|
||||
> docker-compose build --pull hass
|
||||
> docker-compose down hass
|
||||
> docker-compose up -d hass
|
||||
```
|
||||
|
||||
## db
|
||||
Mariadb for Home Assistant use.
|
||||
|
||||
## dbadmin
|
||||
PHPMyAdmin container for tweaking the database if necessary.
|
||||
Start when needed.
|
||||
|
||||
## mqtt
|
||||
Mosquitto server.
|
||||
|
||||
Exposed to IOT network (which is also accessible from LAN thanks to its netmask).
|
||||
|
||||
## influx
|
||||
Storage for Home Assistant sensor data
|
||||
|
||||
## grafana
|
||||
For pretty plotting of data from `influx`
|
||||
|
||||
## deconz
|
||||
Deconz container
|
||||
|
||||
`/dev/conbee` is created on the host by a udev rule in `/etc/udev/rules.d/10-conbee-local.rules`:
|
||||
```
|
||||
ACTION="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", SYMLINK+="conbee"
|
||||
```
|
||||
|
||||
VNC is activated with password `secret`. This is not exposed outside of the docker internal network, though (can be connected to with e.g. a guacamole container).
|
||||
|
||||
A simple healthcheck is added for stability.
|
||||
|
||||
## plejd
|
||||
plejd2mqtt container
|
||||
|
||||
https://github.com/thomasloven/plejd2mqtt - a standalone version of a Home Assistant add-on which connects plejd via bluetooth to MQTT.
|
||||
|
||||
Access to the bluetooth bus is required through `/var/run/dbus`.
|
||||
|
||||
## Mobile
|
||||
pajikos/sms-gammu-gateway exposes GSM modem functionality via REST.
|
||||
|
||||
`/dev/gsmmodem` is created on the host by a udev rule in `/etc/udev/rules.d/999-gsm-modem.rules`:
|
||||
```
|
||||
ACTION=="add", ATTRS{idVendor}=="2001", ATTRS{idProduct}=="ac01", RUN+="/usr/sbin/usb_modeswitch -K -v 2001 -p ac01 -V 2001 -P 7e3d"
|
||||
|
||||
SUBSYSTEM=="tty", ACTION=="add", ENV{ID_VENDOR_ID}=="2001", ENV{ID_MODEL_ID}=="7e3d", ENV{ID_USB_INTERFACE_NUM}=="01", SYMLINK+="gsmmodem"
|
||||
```
|
||||
|
||||
This requires [usb-modeswitch](https://packages.debian.org/bullseye/usb-modeswitch) to be installed on the host, and the exact commands vary greatly from device to device. The above works for my D-Link DWM222, but may or may not work with your D-Link DWM222.
|
||||
|
||||
Health check added for stability
|
@ -8,10 +8,31 @@ networks:
|
||||
lan:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
hass:
|
||||
driver: local
|
||||
driver_opts:
|
||||
o: bind
|
||||
type: none
|
||||
device: /data/files/hass
|
||||
video:
|
||||
driver: local
|
||||
driver_opts:
|
||||
o: bind
|
||||
type: none
|
||||
device: /data/video
|
||||
music:
|
||||
driver: local
|
||||
driver_opts:
|
||||
o: bind
|
||||
type: none
|
||||
device: /data/music
|
||||
|
||||
services:
|
||||
hass:
|
||||
container_name: hass
|
||||
image: homeassistant/home-assistant
|
||||
build: ./hass
|
||||
image: thomasloven/home-assistant
|
||||
restart: always
|
||||
networks:
|
||||
default:
|
||||
@ -19,20 +40,24 @@ services:
|
||||
iot:
|
||||
lan:
|
||||
volumes:
|
||||
- /data/files/hass:/config
|
||||
- hass:/config
|
||||
- video:/media/video
|
||||
- music:/media/music
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
WAITDB_HOST: db
|
||||
WAITDB_USER: hass
|
||||
WAITDB_PASS: hass
|
||||
depends_on:
|
||||
- db
|
||||
working_dir: /config
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: web
|
||||
traefik.http.services.hass.loadbalancer.server.port: 8123
|
||||
traefik.http.routers.hass.rule: HOST(`${HASS_ROOT}`)
|
||||
traefik.http.routers.hass.tls.certResolver: le
|
||||
environment:
|
||||
TZ: Europe/Stockholm
|
||||
|
||||
db:
|
||||
image: mariadb
|
||||
image: mariadb:10.4.12
|
||||
restart: always
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
@ -44,9 +69,22 @@ services:
|
||||
MYSQL_PASSWORD: hass
|
||||
MYSQL_ROOT_PASSWORD: hass
|
||||
|
||||
dbadmin:
|
||||
image: phpmyadmin
|
||||
networks:
|
||||
default:
|
||||
web:
|
||||
environment:
|
||||
PMA_ARBITRARY: 1
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: web
|
||||
traefik.http.routers.dbadmin.rule: HOST(`db.${HASS_ROOT}`)
|
||||
traefik.http.routers.dbadmin.middlewares: auth@file
|
||||
traefik.http.routers.dbadmin.tls.certResolver: le
|
||||
|
||||
mqtt:
|
||||
image: eclipse-mosquitto:latest
|
||||
image: eclipse-mosquitto:1.6
|
||||
restart: always
|
||||
networks:
|
||||
default:
|
||||
@ -55,6 +93,7 @@ services:
|
||||
volumes:
|
||||
- ./mqtt/data:/mosquitto/data
|
||||
- ./mqtt/log:/mosquitto/log
|
||||
#- ./mqtt/config:/mosquitto/config
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
@ -70,10 +109,11 @@ services:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: web
|
||||
traefik.http.routers.grafana.rule: HOST(`grafana.${HASS_ROOT}`)
|
||||
traefik.http.routers.grafana.middlewares: auth@file
|
||||
traefik.http.routers.grafana.tls.certResolver: le
|
||||
|
||||
influx:
|
||||
image: influxdb
|
||||
image: influxdb:1.8
|
||||
restart: always
|
||||
volumes:
|
||||
- ./influx:/var/lib/influxdb
|
||||
@ -87,26 +127,52 @@ services:
|
||||
|
||||
# Devices
|
||||
deconz:
|
||||
image: marthoc/deconz:amd64
|
||||
image: marthoc/deconz:amd64-2.05.77
|
||||
restart: always
|
||||
devices:
|
||||
- /dev/conbee:/dev/ttyUSB0
|
||||
volumes:
|
||||
- ./deconz:/root/.local/share/dresden-elektronik/deCONZ
|
||||
- ./deconz-otau:/root/otau
|
||||
- /etc/timezone:/etc/timezone
|
||||
networks:
|
||||
web:
|
||||
default:
|
||||
# vnc:
|
||||
environment:
|
||||
DECONZ_VNC_MODE: 1
|
||||
DECONZ_VNC_PASSWORD: secret
|
||||
DEBUG_OTAU: 1
|
||||
DECONZ_WEB_PORT: 8081
|
||||
ports:
|
||||
- 8081:8081
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: web
|
||||
traefik.http.services.deconz.loadbalancer.server.port: 80
|
||||
traefik.http.routers.deconz.rule: HOST(`deconz.avagen.${PRIVATE_DOMAIN}`)
|
||||
traefik.http.services.deconz.loadbalancer.server.port: 8081
|
||||
traefik.http.routers.deconz.rule: HOST(`deconz.${HASS_ROOT}`)
|
||||
traefik.http.routers.deconz.middlewares: auth@file
|
||||
traefik.http.routers.deconz.tls.certResolver: le
|
||||
healthcheck:
|
||||
test: curl http://localhost:5900 || exit 1
|
||||
|
||||
# mysensors:
|
||||
# rflink:
|
||||
|
||||
plejd:
|
||||
image: thomasloven/plejd2mqtt
|
||||
restart: always
|
||||
environment:
|
||||
PLEJD_SITE:
|
||||
PLEJD_USERNAME:
|
||||
PLEJD_PASSWORD:
|
||||
MQTT_BROKER: mqtt://mqtt
|
||||
volumes:
|
||||
- /var/run/dbus:/var/run/dbus
|
||||
|
||||
mobile:
|
||||
image: pajikos/sms-gammu-gateway
|
||||
restart: always
|
||||
devices:
|
||||
- /dev/gsmmodem:/dev/mobile
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-O", "-", "localhost:5000/signal"]
|
||||
|
41
hass/Dockerfile
Normal file
41
hass/Dockerfile
Normal file
@ -0,0 +1,41 @@
|
||||
ARG HASS_VERSION=latest
|
||||
|
||||
FROM homeassistant/home-assistant:$HASS_VERSION
|
||||
|
||||
RUN apk add --update-cache zbar mysql-client \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Check if root
|
||||
# If running as root, remove setuid and setgid flags of everything
|
||||
# Then add a hass user and make that the owner of /config
|
||||
# Finally, make pip install to user folders
|
||||
RUN python3 -c 'import os; assert os.geteuid() == 0, "Already non-root! Skip changing user"' \
|
||||
&& find / -xdev -type f -perm /u+s -exec chmod -c u-s {} \; \
|
||||
&& find / -xdev -type f -perm /g+s -exec chmod -c g-s {} \; \
|
||||
&& adduser -D hass \
|
||||
&& addgroup hass dialout \
|
||||
&& chown hass /config \
|
||||
&& mkdir -p ~hass/.config/pip \
|
||||
&& chown hass ~hass/.config \
|
||||
&& chown hass ~hass/.config/pip \
|
||||
&& echo -e '[install]\nuser = yes' > ~hass/.config/pip/pip.conf \
|
||||
&& mkdir -p ~hass/.local/lib \
|
||||
&& chown hass ~hass/.local \
|
||||
&& chown hass ~hass/.local/lib
|
||||
|
||||
COPY wait-for-db.sh /home/hass/wait-for-db.sh
|
||||
RUN chmod +x /home/hass/wait-for-db.sh
|
||||
|
||||
USER hass
|
||||
|
||||
# Make /config persistent even if not mounted
|
||||
VOLUME /config
|
||||
# Make pip cache persistent
|
||||
VOLUME /home/hass/.local/lib
|
||||
WORKDIR /config
|
||||
# Export default port for use with routers like traefik
|
||||
EXPOSE 8123/tcp
|
||||
|
||||
CMD ["/home/hass/wait-for-db.sh", "python3", "-m", "homeassistant", "-v", "--config", "/config"]
|
||||
|
||||
HEALTHCHECK CMD curl http://localhost:8123/ || exit 1
|
21
hass/wait-for-db.sh
Normal file
21
hass/wait-for-db.sh
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# wait-for-db.sh
|
||||
|
||||
set -e
|
||||
|
||||
host=${WAITDB_HOST}
|
||||
user=${WAITDB_USER}
|
||||
pass=${WAITDB_PASS}
|
||||
|
||||
echo "$host $user $pass"
|
||||
|
||||
if [[ -v host ]]; then
|
||||
until mysql --host="$host" --user="$user" --password="$pass" -e '\q'; do
|
||||
>&2 echo "Database unavailable - sleeping"
|
||||
sleep 1
|
||||
done
|
||||
>&2 echo "Database available!"
|
||||
fi
|
||||
|
||||
>&2 echo "Executing command"
|
||||
exec "$@"
|
Loading…
x
Reference in New Issue
Block a user