Skip to content

Commit

Permalink
feat: added Docker configuration
Browse files Browse the repository at this point in the history
A release will trigger an automatic build of a multi-arch Docker image
that can be used on most Docker platforms, including the Raspberry Pi.
  • Loading branch information
mKeRix committed Feb 11, 2020
1 parent 2088503 commit 546fe62
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
@@ -0,0 +1,3 @@
*
!docker/
!/*.tgz
25 changes: 25 additions & 0 deletions .github/workflows/docker.yml
@@ -0,0 +1,25 @@
name: Docker

on:
push:
tags:
- v*

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Login to DockerHub Registry
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
- name: Set up Docker Buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v1
with:
version: latest
- name: Run Buildx
run: docker buildx build --build-arg ROOM_ASSISTANT_VERSION=${{steps.get_version.outputs.VERSION}} --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64 -t mkerix/room-assistant:${{steps.get_version.outputs.VERSION}} --push .
2 changes: 2 additions & 0 deletions .github/workflows/gh-pages.yml
Expand Up @@ -2,6 +2,8 @@ name: Documentation

on:
push:
paths:
- 'docs/**'
branches:
- nextgen

Expand Down
22 changes: 22 additions & 0 deletions Dockerfile
@@ -0,0 +1,22 @@
FROM node:12-alpine as build
ARG ROOM_ASSISTANT_VERSION=latest

RUN apk add --no-cache python make g++ libusb-dev eudev-dev avahi-dev
RUN npm install -g --unsafe-perm room-assistant@$ROOM_ASSISTANT_VERSION

FROM node:12-alpine

WORKDIR /room-assistant

RUN apk add --no-cache supervisor bluez bluez-deprecated libusb avahi avahi-dev dmidecode \
&& mkdir -p /var/run/dbus \
&& setcap cap_net_raw+eip $(eval readlink -f `which node`) \
&& setcap cap_net_raw+eip $(eval readlink -f `which hcitool`) \
&& addgroup --gid 998 i2c \
&& addgroup node i2c \
&& ln -s /usr/local/lib/node_modules/room-assistant/bin/room-assistant.js /usr/local/bin/room-assistant
COPY docker/supervisord.conf docker/entrypoint.sh /etc/
COPY --from=build /usr/local/lib/node_modules/room-assistant /usr/local/lib/node_modules/room-assistant

ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/etc/entrypoint.sh"]
23 changes: 23 additions & 0 deletions dev.Dockerfile
@@ -0,0 +1,23 @@
FROM node:12-alpine as build
WORKDIR /room-assistant

RUN apk add --no-cache python make g++ libusb-dev eudev-dev avahi-dev
COPY ./*.tgz /room-assistant/
RUN npm install -g --unsafe-perm *.tgz

FROM node:12-alpine

WORKDIR /room-assistant

RUN apk add --no-cache supervisor bluez bluez-deprecated libusb avahi avahi-dev dmidecode \
&& mkdir -p /var/run/dbus \
&& setcap cap_net_raw+eip $(eval readlink -f `which node`) \
&& setcap cap_net_raw+eip $(eval readlink -f `which hcitool`) \
&& addgroup --gid 998 i2c \
&& addgroup node i2c \
&& ln -s /usr/local/lib/node_modules/room-assistant/bin/room-assistant.js /usr/local/bin/room-assistant
COPY docker/supervisord.conf docker/entrypoint.sh /etc/
COPY --from=build /usr/local/lib/node_modules/room-assistant /usr/local/lib/node_modules/room-assistant

ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/etc/entrypoint.sh"]
15 changes: 11 additions & 4 deletions docker-compose.yml
@@ -1,6 +1,13 @@
version: '3'
services:
mqtt:
image: eclipse-mosquitto:1.6
ports:
- 1883:1883
room-assistant:
build: .
network_mode: host
environment:
NODE_CONFIG: >
{
"global": {
"instanceName": "dev-instance",
"integrations": []
}
}
6 changes: 6 additions & 0 deletions docker/entrypoint.sh
@@ -0,0 +1,6 @@
echo "Starting DBUS daemon..."
dbus-uuidgen > /var/lib/dbus/machine-id
dbus-daemon --config-file=/usr/share/dbus-1/system.conf

echo "Starting supervisor..."
exec supervisord -c /etc/supervisord.conf
19 changes: 19 additions & 0 deletions docker/supervisord.conf
@@ -0,0 +1,19 @@
[supervisord]
nodaemon=true
user=root

[program:avahi-daemon]
command=avahi-daemon
priority=50
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:room-assistant]
command=room-assistant
user=node
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
31 changes: 26 additions & 5 deletions docs/guide/configuration.md
@@ -1,14 +1,35 @@
# Configuration

room-assistant can be configured using YAML and JSON files. It will look for them in the `config` subdirectory of the current working directory.
The files in the config folder are loaded according to a [specific order](https://github.com/lorenwest/node-config/wiki/Configuration-Files#file-load-order) and then merged into a single configuration.
In most cases you should only need a single file called `local.yml` or `local.json` in the config folder though.
room-assistant can be configured using YAML and JSON files. It will look for them in the `config` subdirectory of the current working directory. The files in the config folder are loaded according to a [specific order](https://github.com/lorenwest/node-config/wiki/Configuration-Files#file-load-order) and then merged into a single configuration. In most cases you should only need a single file called `local.yml` or `local.json` in the config folder though.

For example, let's say you are launching room-assistant from the directory `/home/pi/room-assistant`.
In this case you should create a file `/home/pi/room-assistant/config/local.yml` and put your configuration in there.
For example, let's say you are launching room-assistant from the directory `/home/pi/room-assistant`. In this case you should create a file `/home/pi/room-assistant/config/local.yml` and put your configuration in there.

You can find the global configuration options below and the ones specific to some integrations on their respective pages.

## Configuring with Docker

The official [Docker image](https://hub.docker.com/r/mkerix/room-assistant/) can be configured in two different ways. You can either mount your local config folder into the container as `/room-assistant/config` or you can provide the configuration as JSON through an environment variable.

::: details Example docker-compose.yml

```yaml
version: '3'
services:
room-assistant:
image: mkerix/room-assistant
network_mode: host
environment:
NODE_CONFIG: >
{
"global": {
"instanceName": "living-room",
"integrations": ["homeAssistant", "bluetoothClassic"]
}
}
```

:::

## Core Settings

**Config Key:** `global`
Expand Down
4 changes: 4 additions & 0 deletions docs/guide/installation.md
Expand Up @@ -26,6 +26,10 @@ sudo npm i --global --unsafe-perm room-assistant
npm will link the binary for running the software, usually into `/usr/bin/room-assistant`.
If the directory is already in your `PATH` you can start it directly by typing `room-assistant`. Otherwise you can start it by typing the full path name of where it was installed.

## Running with Docker

This project provides official Docker images on [Docker Hub](https://hub.docker.com/r/mkerix/room-assistant/). You can either use the latest or a specific version by using the correct tag. It is strongly recommended to run this image with the `host` network, otherwise you may run into problems with many parts of the software.

## Running with Hass.io

You can install room-assistant as Hass.io add-on by [adding the following URL as repository](https://www.home-assistant.io/hassio/installing_third_party_addons/):
Expand Down
20 changes: 20 additions & 0 deletions src/integrations/home-assistant/home-assistant.service.spec.ts
Expand Up @@ -299,6 +299,26 @@ describe('HomeAssistantService', () => {
});
});

it('should make the instance name the device identifier if no serial was found', async () => {
mockSystem.mockResolvedValue({
serial: '-',
model: 'Docker Container',
manufacturer: ''
} as SystemData);

await service.onModuleInit();
service.handleNewEntity(new Sensor('grideye-sensor', 'GridEYE Sensor'));

expect(JSON.parse(mockMqttClient.publish.mock.calls[0][1])).toMatchObject({
device: {
identifiers: 'test-instance',
name: 'test-instance',
model: 'Docker Container',
manufacturer: ''
}
});
});

it('should apply sensor customizations to the discovery message', async () => {
await service.onModuleInit();
service.handleNewEntity(new Sensor('custom-sensor', 'Custom'), [
Expand Down
9 changes: 7 additions & 2 deletions src/integrations/home-assistant/home-assistant.service.ts
Expand Up @@ -222,9 +222,14 @@ export class HomeAssistantService
* @returns Device information
*/
protected async getDeviceInfo(): Promise<Device> {
const instanceName = this.configService.get('global').instanceName;
const systemInfo = await system();
const device = new Device(systemInfo.serial);
device.name = this.configService.get('global').instanceName;
const serial =
systemInfo.serial && systemInfo.serial !== '-'
? systemInfo.serial
: makeId(instanceName);
const device = new Device(serial);
device.name = instanceName;
device.model = systemInfo.model;
device.manufacturer = systemInfo.manufacturer;
return device;
Expand Down

0 comments on commit 546fe62

Please sign in to comment.