roles/homeassistant: Deploy container with Podman
Installing Home Assistant in a Python virtualenv is rather tedious, especially on non-x86 machines. The main issue is Python packages that include native extensions, as many of these do not have binary wheels available for aarch64, etc. on PyPI. Thus, to install these, they have to be built from source, which then requires the appropriate development packages to be installed. Additionally, compiling native code on a Raspberry Pi is excruciatingly slow. I have considered various ways of mitigating this, but all would require a substantial time investment, both up front and ongoing, making them rather pointless. Eventually, I settled on just deploying the official Home Assistant container image with Podman. Although Podman includes a tool for generating systemd service unit files for running containers, I ended up creating my own for several reasons. First and foremost, the generated unit files configure the containers to run as *root*, but I wanted to run Home Assistant as an unprivileged user. Unfortunately, I could not seem to get the container to work when dropping privileges using the `User` directive of the unit. Fortunately, `podman` has `--uidmap` and `--gidmap` arguments, which I was able to use to map UID/GID 0 in the container to the *homeassistant* user on the host. Another drawback of the generated unit files is that they specify a "forking" type service, which is not really necessary. Podman/conmon supports the systemd notify protocol, but the generator has not been updated to make use of that yet. Recent versions of Home Assistant are more strict with respect to how reverse proxies are handled. In order to use one, it must be explicitly listed in the configuration file. Therefore, the *homeassistant* Ansible role will now create a stub `configuration.yaml`, based on the one generated by Home Assistant itslf when it starts for the first time on a new machine, that includes the appropriate configuration for a reverse proxy running on the same machine. The stub configuration will not overwrite an existing configuration file, so it is only useful when deploying Home Assistant for the first time on a new machine. Overall, although I think a 300+ MB container image is ridiculous, deploying Home Assistant this way should make it a lot easier to manage, especially when updating.jenkins-master
parent
4aa3cdddd9
commit
288b050a33
|
@ -1,7 +1,8 @@
|
||||||
- hosts: home-assistant
|
- hosts: home-assistant
|
||||||
roles:
|
roles:
|
||||||
- apache
|
- apache
|
||||||
- homeassistant
|
- role: homeassistant
|
||||||
|
tags: homeassistant
|
||||||
- role: mosquitto
|
- role: mosquitto
|
||||||
tags: mosquitto
|
tags: mosquitto
|
||||||
tasks:
|
tasks:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
homeassistant_image_name: '{{ homeassistant_default_image_name }}'
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
exec /usr/local/homeassistant/bin/hass
|
|
|
@ -1,13 +0,0 @@
|
||||||
# vim: set ft=systemd :
|
|
||||||
[Unit]
|
|
||||||
Description=Home Assistant
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
Environment=TMPDIR=/var/lib/homeassistant/tmp
|
|
||||||
ExecStart=/usr/local/bin/hass
|
|
||||||
User=homeassistant
|
|
||||||
UMask=0077
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
server_host: '::1'
|
||||||
|
trusted_proxies:
|
||||||
|
- '::1'
|
||||||
|
use_x_forwarded_for: true
|
|
@ -0,0 +1 @@
|
||||||
|
[]
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
# Configure a default setup of Home Assistant (frontend, api, etc)
|
||||||
|
default_config:
|
||||||
|
|
||||||
|
http: !include http.yaml
|
||||||
|
|
||||||
|
# Text to speech
|
||||||
|
tts:
|
||||||
|
- platform: google_translate
|
||||||
|
|
||||||
|
group: !include groups.yaml
|
||||||
|
automation: !include automations.yaml
|
||||||
|
script: !include scripts.yaml
|
||||||
|
scene: !include scenes.yaml
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -3,11 +3,12 @@
|
||||||
with_first_found:
|
with_first_found:
|
||||||
- '{{ ansible_architecture }}.yml'
|
- '{{ ansible_architecture }}.yml'
|
||||||
- defaults.yml
|
- defaults.yml
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
- name: ensure system dependencies are installed
|
- name: ensure podman is installed
|
||||||
package:
|
package:
|
||||||
name: >-
|
name: '{{ homeassistant_podman_packages }}'
|
||||||
{{ homeassistant_common_system_deps + homeassistant_arch_system_deps }}
|
|
||||||
state: present
|
state: present
|
||||||
tags:
|
tags:
|
||||||
- install
|
- install
|
||||||
|
@ -17,62 +18,73 @@
|
||||||
name: homeassistant
|
name: homeassistant
|
||||||
system: true
|
system: true
|
||||||
home: /var/lib/homeassistant
|
home: /var/lib/homeassistant
|
||||||
|
createhome: false
|
||||||
|
register: homeassistant_user
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
|
||||||
- name: ensure homeassistant tmp dir exists
|
- name: ensure homeassistant home directory exists
|
||||||
file:
|
file:
|
||||||
path: /var/lib/homeassistant/tmp
|
path: /var/lib/homeassistant
|
||||||
mode: '0700'
|
|
||||||
owner: homeassistant
|
owner: homeassistant
|
||||||
group: homeassistant
|
group: homeassistant
|
||||||
state: directory
|
|
||||||
|
|
||||||
- name: ensure homeassistant install dir exists
|
|
||||||
file:
|
|
||||||
path: /usr/local/homeassistant
|
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
owner: homeassistant
|
|
||||||
group: homeassistant
|
|
||||||
state: directory
|
state: directory
|
||||||
- name: ensure homeassistant is installed
|
tags:
|
||||||
environment:
|
- datadir
|
||||||
TMPDIR: /var/lib/homeassistant/tmp
|
|
||||||
become: true
|
|
||||||
become_user: homeassistant
|
|
||||||
pip:
|
|
||||||
name: homeassistant
|
|
||||||
extra_args: >-
|
|
||||||
--prefer-binary
|
|
||||||
virtualenv: /usr/local/homeassistant
|
|
||||||
virtualenv_command: '/usr/bin/python3 -m venv'
|
|
||||||
|
|
||||||
- name: ensure selinux file context map is correct for home assistant dir
|
- name: ensure stub home assistant configuration is set
|
||||||
sefcontext:
|
|
||||||
ftype: a
|
|
||||||
setype: bin_t
|
|
||||||
target: /usr/local/homeassistant/bin(/.*)?
|
|
||||||
state: present
|
|
||||||
notify: relabel home assistant dir
|
|
||||||
|
|
||||||
- name: ensure homeassistant entry point is installed
|
|
||||||
copy:
|
copy:
|
||||||
src: hass.sh
|
src: '{{ item }}'
|
||||||
dest: /usr/local/bin/hass
|
dest: /var/lib/homeassistant/{{ item|basename }}
|
||||||
setype: bin_t
|
owner: homeassistant
|
||||||
mode: '0755'
|
group: homeassistant
|
||||||
|
mode: '0644'
|
||||||
|
force: false
|
||||||
|
with_fileglob:
|
||||||
|
- 'stubs/*.yaml'
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
- name: ensure home assistant proxy settings are configured
|
||||||
|
copy:
|
||||||
|
src: http.yaml
|
||||||
|
dest: /var/lib/homeassistant/http.yaml
|
||||||
|
owner: homeassistant
|
||||||
|
group: homeassistant
|
||||||
|
mode: '0644'
|
||||||
notify:
|
notify:
|
||||||
- restart homeassistant
|
- restart homeassistant
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
|
||||||
|
- name: ensure homeassistant container image is available
|
||||||
|
podman_image:
|
||||||
|
name: ghcr.io/home-assistant/{{ homeassistant_image_name }}
|
||||||
|
tag: stable
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- restart homeassistant
|
||||||
|
tags:
|
||||||
|
- container-image
|
||||||
|
- container
|
||||||
|
|
||||||
- name: ensure homeassistant systemd unit is installed
|
- name: ensure homeassistant systemd unit is installed
|
||||||
copy:
|
template:
|
||||||
src: homeassistant.service
|
src: homeassistant.service.j2
|
||||||
dest: /etc/systemd/system/homeassistant.service
|
dest: /etc/systemd/system/homeassistant.service
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
notify:
|
notify:
|
||||||
- reload systemd
|
- reload systemd
|
||||||
- restart homeassistant
|
- restart homeassistant
|
||||||
|
tags:
|
||||||
|
- service
|
||||||
|
- systemd
|
||||||
- name: ensure homeassistant starts at boot
|
- name: ensure homeassistant starts at boot
|
||||||
service:
|
service:
|
||||||
name: homeassistant
|
name: homeassistant
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tags:
|
||||||
|
- service
|
||||||
|
|
||||||
- name: ensure apache is configured to proxy for homeassistant
|
- name: ensure apache is configured to proxy for homeassistant
|
||||||
template:
|
template:
|
||||||
|
@ -81,8 +93,13 @@
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
notify:
|
notify:
|
||||||
- restart httpd
|
- restart httpd
|
||||||
|
tags:
|
||||||
|
- apache
|
||||||
- name: ensure selinux allows apache to proxy
|
- name: ensure selinux allows apache to proxy
|
||||||
seboolean:
|
seboolean:
|
||||||
name: httpd_can_network_connect
|
name: httpd_can_network_connect
|
||||||
state: true
|
state: true
|
||||||
persistent: true
|
persistent: true
|
||||||
|
tags:
|
||||||
|
- selinux
|
||||||
|
- apache
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
homeassistant:
|
|
||||||
# Name of the location where Home Assistant is running
|
|
||||||
name: Home
|
|
||||||
# Location required to calculate the time the sun rises and sets
|
|
||||||
latitude: 38.9568
|
|
||||||
longitude: -94.6832
|
|
||||||
# Impacts weather/sunrise data (altitude above sea level in meters)
|
|
||||||
elevation: 0
|
|
||||||
# metric for Metric, imperial for Imperial
|
|
||||||
unit_system: imperial
|
|
||||||
# Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
||||||
time_zone: America/Chicago
|
|
||||||
# Customization file
|
|
||||||
customize: !include customize.yaml
|
|
||||||
|
|
||||||
# Configure a default setup of Home Assistant (frontend, api, etc)
|
|
||||||
default_config:
|
|
||||||
|
|
||||||
# Show the introduction message on startup.
|
|
||||||
introduction:
|
|
||||||
|
|
||||||
# Uncomment this if you are using SSL/TLS, running in Docker container, etc.
|
|
||||||
# http:
|
|
||||||
# base_url: example.duckdns.org:8123
|
|
||||||
http:
|
|
||||||
server_host: '::1'
|
|
||||||
|
|
||||||
# Sensors
|
|
||||||
sensor: !include sensors.yaml
|
|
||||||
|
|
||||||
# Text to speech
|
|
||||||
tts:
|
|
||||||
- platform: google
|
|
||||||
|
|
||||||
group: !include groups.yaml
|
|
||||||
automation: !include automations.yaml
|
|
||||||
script: !include scripts.yaml
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# vim: set ft=systemd :
|
||||||
|
[Unit]
|
||||||
|
Description=Home Assistant
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
ExecStartPre=-/usr/bin/podman container rm --ignore -f homeassistant
|
||||||
|
ExecStart=/usr/bin/podman run \
|
||||||
|
--sdnotify=conmon --cgroups=no-conmon \
|
||||||
|
--rm \
|
||||||
|
--network=host \
|
||||||
|
--name homeassistant \
|
||||||
|
-v /var/lib/homeassistant:/config:Z \
|
||||||
|
--uidmap 0:{{ homeassistant_user.uid }}:1 \
|
||||||
|
--gidmap 0:{{ homeassistant_user.group }}:1 \
|
||||||
|
--uidmap 1:4000000:65536 \
|
||||||
|
--gidmap 1:4000000:65536 \
|
||||||
|
ghcr.io/home-assistant/{{ homeassistant_image_name }}:stable
|
||||||
|
ProtectSystem=full
|
||||||
|
UMask=0077
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1 @@
|
||||||
|
homeassistant_default_image_name: aarch64-homeassistant
|
|
@ -1,12 +1 @@
|
||||||
# These are required to build Python packages that do not have wheels
|
homeassistant_default_image_name: armhf-homeassistant
|
||||||
# on pypi.org for armv7hl
|
|
||||||
homeassistant_arch_system_deps:
|
|
||||||
- gcc
|
|
||||||
- gcc-c++
|
|
||||||
- libffi-devel
|
|
||||||
- libopenzwave-devel
|
|
||||||
- libudev-devel
|
|
||||||
- make
|
|
||||||
- openssl-devel
|
|
||||||
- python3-devel
|
|
||||||
- which
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
homeassistant_arch_system_deps: []
|
homeassistant_default_image_name: home-assistant
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
homeassistant_common_system_deps:
|
homeassistant_podman_packages:
|
||||||
- python3-pip
|
- podman
|
||||||
|
- catatonit
|
||||||
|
|
Loading…
Reference in New Issue