homebridge / homebridge

HomeKit support for the impatient.
https://homebridge.io
Apache License 2.0
24.09k stars 1.99k forks source link

Dockerizing #309

Closed patrickbusch closed 7 years ago

patrickbusch commented 9 years ago

Hi,

I have great experiences with docker and want to encapsulate homebridge within a docker image.

This makes it runnable on every device which has docker support (e.g. some NAS like Synology)

Question:

Branch it here or do it in my own repository with a submodule link to here?

tokamac commented 9 years ago

Someone tried the docker solution and since it didn't work for him, used Debian Chroot instead: http://jensbouma.nl/hello-siri-turn-the-lights-on-the-siri-for-iot-bridge-running-on-a-synology-nas/

tokamac commented 9 years ago

Do you know if Node.js version 4.x can compile on ARMv7 NAS like Synology DS215j (Armada 375) or DS215+ (Alpine AL212) or are these models limited to node v0.12.x?

patrickbusch commented 9 years ago

Docker can run on those models:

https://www.synology.com/de-de/dsm/app_packages/Docker

I do not know if Node can compile directly on an ARM NAS unfortunately

dobsiin commented 9 years ago

i've also tried to do a dockerrized version. it runs fine (dobsiin/fhem), but i cant get it in the eve elgato app, I really tried every port setting there is available. normally it is 51826 thought it would be enough to run homebridge inside a container. hopefully someone will figure it out. guess i'm going with chroot now.

patrickbusch commented 9 years ago

Hey, my approach works:

https://github.com/patrickbusch/homebridge-docker

The trick for me was that it needs to be run with --net=host, otherwise the avahi-daemon would not be accessible from the outside. This works on an PI with Hypriot OS (Raspbian with recompiled kernel for docker support) Linux should also be fine, on a Mac however you may have to fiddle with the Ports to the Docker VM ;)

Cheers

dobsiin commented 9 years ago

Thank you!!!

I'm now able to run the homebridge docker container on my synology nas. Like you said the trick was --net=host which is unfortunately only available when you ssh into your synology nas and run the container with the docker run -d --net=host -p 51826:51826 homebridge cmd there.

patrickbusch commented 9 years ago

Glad it worked :D

udochrist commented 8 years ago

@dobsiin How did you install/build/run on the syno? All from command line or is there any possibility to use the gui besides for the running of the container?

dobsiin commented 8 years ago

I built the image on my computer with the docker toolbox with the cmd like docker build -t dobsiin/homebridge /path/to/Dockerfile then i pushed the built image to my docker hub docker push dobsiin/homebridge i personally would not do the build process on the syno. then simply download the image with docker pull dobsiin/homebridge or download the docker image with the GUI from syno.

but to be able to run it you have to use ssh and the full range of docker cmd's because the problem is the syno GUI for docker is no capable of adding the option --net=host.

The GUI is only good for downloading images, and monitoring the container.

snizzleorg commented 8 years ago

Has someone got @patrickbusch docker image running on an raspberry pi?

benbeton commented 8 years ago

@patrickbusch @snizzleorg thanks guys, my Homebridge Docker image is running.

But there is a strange behaviour:

Everytime I stop the container (homebridge-pi.sh stop) and then start the container (homebridge-pi.sh start) there is a homebridge error and the container stops.

Homebridge is running on port 51826.
/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:56
  dns_sd.DNSServiceRegister(self.serviceRef, flags, ifaceIdx, name,
         ^
Error: dns service error: unknown
    at Error (native)
    at new Advertisement (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:56:10)
    at Object.create [as createAdvertisement] (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:64:10)
    at Advertiser.startAdvertising (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Advertiser.js:43:30)
    at Bridge.Accessory._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:352:20)
    at HAPServer.emit (events.js:104:17)
    at HAPServer._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/HAPServer.js:153:8)
    at EventedHTTPServer.emit (events.js:104:17)
    at EventedHTTPServer.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/util/eventedhttp.js:62:10)
    at Server.emit (events.js:104:17)
    at net.js:1171:12
    at process._tickCallback (node.js:355:11)

Only (homebridge-pi.sh remove / homebridge-pi.sh run) will work then.

The problem after that, I have to re-add Homebridge to Homekit in iOS, then it works until next rerun. This is not a good workaround cause after re-adding Homebridge to HomeKit all the configuraiton is gone (rooms, Scenes...)

The config.json is not changed, ID and MAC of HomeBridge are same, but the iOS device did not connect after rerun. Maybe there is more, that identifies Homebridge

any idea what cause the crash?

snizzleorg commented 8 years ago

I have the same problem. No idea how to fix it however.

patrickbusch commented 8 years ago

I have not myself found a solution for this problem. It has something to do the mdns advertisement, this only works correctly in docker when it has direct access to the hosts network interface (hence --net=hosts in the run script). When stopping the container this gets not cleaned correctly. Maybe we can clean the host interface after stopping the container, that could work

snizzleorg commented 8 years ago

well but still after restarting the whole raspberry pi i still have to re-add home bridge on the iPhone.. that can't really be an mdns problem - can it?

and the re-adding only works if I change the name - so iOS recognises home bridge a s a new accessory

benbeton commented 8 years ago

re-adding works for me without changing the name, but at first, I have to delete the current accessory. After that I can re-add Homebridge again, with the same name

snizzleorg commented 8 years ago

yeah but doing this every time home bridge is restarted is very annoying...

benbeton commented 8 years ago

sure, maybe we should dockerize pimatic and run hombridge nativ?!

Could it be possbile that there a other files, not only the config.json that makes homebridge instance uniqe? If yes, maybe they can maintained when running a rerun. Cause when I reinstalled a not dockerized homebridge installaiton I backed-up and restored the config.json but still have to re-add homebridge

At home I will check with bonjour browser if something changes in hab if you rerun the docker image.

patrickbusch commented 8 years ago

If I recall correctly there is something written to the home-directory by homebridge. I cannot check right now. exposing this as volume could help

benbeton commented 8 years ago

so if you do homebridge-pi.sh attach you will find:

root@razberry:~/.homebridge/persist# ls -la
total 24
drwxr-xr-x 2 root root 4096 Dec 15 11:57 .
drwxr-xr-x 1 root root 4096 Dec 15 11:56 ..
-rw-r--r-- 1 root root  491 Dec 15 17:30 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 8317 Dec 15 17:30 IdentifierCache.CC223DE3CE30.json

they seem to have the timestamp when started homebridge. These files maybe should be persistent, will they be deleted while stopping the container?!

If they are needed, to reconnect to homebridge, how could they made persistant inside the container?

nfarina commented 8 years ago

The persist directory contains important data about paired iOS devices and should not be deleted. If you are running in a container you will need to ensure this directory survives. You can customize the location of the directory using a command-line parameters (pass in --help for more info)

benbeton commented 8 years ago

I had no chance to see if the files are changing when running start / stop (container exit) but the AccessoryInfo.CC223DE3CE30.json is changing when running rerun (stop / remove / run)

patrickbusch commented 8 years ago

I adapted the run script to use a volume for .homebridge. Can you check if this solves your problem?

benbeton commented 8 years ago

thanks, still the same, where is that volume mounted? (root/.homebridge)?

patrickbusch commented 8 years ago

you can run docker inspect homebridge-pi-v0.1-SNAPSHOT

in the mounts section you can see the dir on the host system.

if you want a certain dir, you can adapt homebridge-common.sh in run method:

Docker syntax is -v /path/on/host:/path/in/container

snizzleorg commented 8 years ago

I created a pull request so that the config folder will be kept on the host. I could not verify whether it works though. If someone can test it here it is:

https://github.com/snizzleorg/homebridge-docker

for info on the volume option of docker see here:

https://docs.docker.com/engine/userguide/dockervolumes/

patrickbusch commented 8 years ago

looks good. config.json can also be outside, yes.

We should also think about how we can configure what plugins to install (at creation of container).

I already have an idea - configure it in an additional file (plugins), add that at the build stage and perform installs according to it. I will give it a try in the next days

benbeton commented 8 years ago

I'll test laster today. looks good means it is working on your iOS Device, you don't have to delete the Home in Homekit after rerun?!

patrickbusch commented 8 years ago

I'm not at home so I couldn't test, I just checked the code changes

benbeton commented 8 years ago

works for me! config is maintained, no need to re-add Homebridge after homebridge-pi.sh rerun thx!

snizzleorg commented 8 years ago

I do have the same problem again, although the persist folder is outside of the container:

Homebridge is running on port 51826.
/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:56
  dns_sd.DNSServiceRegister(self.serviceRef, flags, ifaceIdx, name,
         ^
Error: dns service error: unknown
    at Error (native)
    at new Advertisement (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:56:10)
    at Object.create [as createAdvertisement] (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/node_modules/mdns/lib/advertisement.js:64:10)
    at Advertiser.startAdvertising (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Advertiser.js:43:30)
    at Bridge.Accessory._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:352:20)
    at HAPServer.emit (events.js:104:17)
    at HAPServer._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/HAPServer.js:153:8)
    at EventedHTTPServer.emit (events.js:104:17)
    at EventedHTTPServer.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/util/eventedhttp.js:62:10)
    at Server.emit (events.js:104:17)
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Failed to start message bus: The pid file "/var/run/dbus/pid" exists, if the message bus is not running, remove this file
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>

checking with bonjour browser i see indeed that the service is still registered even if the raspberry pi is reset.

snizzleorg commented 8 years ago

actually for whatever reason the persist files are getting overwritten and are 0 file size. so this might be the cause of the problem?


ls -l /etc/homebridge/persist/
total 0
-rw-r--r-- 1 root root 0 Jan  6 16:47 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 0 Jan  6 16:47 IdentifierCache.CC223DE3CE30.json
snizzleorg commented 8 years ago

If I use rerun it works and no error is produced then the file sin the persist folder have a non-zero size after stoping and starting the files get reset...

steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
total 20K
-rw-r--r-- 1 root root 389 Jan  6 17:07 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 14K Jan  6 17:07 IdentifierCache.CC223DE3CE30.json
steffen@automator ~/src/homebridge-docker $ ./homebridge-pi.sh stop
homebridge-pi-v0.1-SNAPSHOT
steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
total 20K
-rw-r--r-- 1 root root 389 Jan  6 17:07 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 14K Jan  6 17:07 IdentifierCache.CC223DE3CE30.json
steffen@automator ~/src/homebridge-docker $ ./homebridge-pi.sh start
homebridge-pi-v0.1-SNAPSHOT
steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
total 20K
-rw-r--r-- 1 root root 389 Jan  6 17:07 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 14K Jan  6 17:07 IdentifierCache.CC223DE3CE30.json
steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
total 20K
-rw-r--r-- 1 root root 389 Jan  6 17:07 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 14K Jan  6 17:07 IdentifierCache.CC223DE3CE30.json
steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
total 0
-rw-r--r-- 1 root root 0 Jan  6 17:10 AccessoryInfo.CC223DE3CE30.json
-rw-r--r-- 1 root root 0 Jan  6 17:10 IdentifierCache.CC223DE3CE30.json
steffen@automator ~/src/homebridge-docker $ ls -lh /etc/homebridge/persist/
cbrandlehner commented 8 years ago

For those curious about running the docker image on a synology NAS: It works well in my environment with the --net=host parameter.

acseven commented 8 years ago

@cbrandlehner How did you specifically add that parameter in your Synology? Using the gui?

As for the mdns error a few others mentioned ( @patrickbusch @benbeton @snizzleorg ), although I haven't figured out why it happens, I've found that running this after booting gets it running again:

/etc/init.d/dbus restart 
service avahi-daemon start 
service avahi-daemon start 

The avahi-daemon line is entered twice because the first time it runs it always returns an error, but runs fine the second time.

cbrandlehner commented 8 years ago

@acseven I do not use the GUI. I created a file homebridge.sh with this content:

docker run -d --net=host -p 51826:51826 -v /volume3/docker/homebridge:/root/.homebridge cbrandlehner/homebridge:0.6-SNAPSHOT

To start the docker container I have to log in via SSH and start the script.

snizzleorg commented 8 years ago

@acseven @cbrandlehner @patrickbusch you have to restart bus in the container? or on the host (that does not really make sense after rebooting - doesn't it? And if in the container then it probably needs to be integrated in the startupscript inside the container - right?

I tried rebooting the host and then starting bus but that did not work. ./homebridge-pi.sh start gives

Error response from daemon: Cannot start container homebridge-pi-v0.1-SNAPSHOT: [8] System error: dbus: connection closed by user
Error: failed to start containers: [homebridge-pi-v0.1-SNAPSHOT]

I still have to change the name in config.json and delete the persist files. Then of course in iOS homekitbridge has to be added again and everything has to be configured again.

tahitibub commented 8 years ago

@cbrandlehner

Hi,

I've been trying to install HomeKitBridge-Vera on my Synology using Docker for one week now, without success. It's very frustating ...

I tried a lot of things, following these tutoriels : http://forum.micasaverde.com/index.php/topic,31716.msg237385.html#msg237385 http://forum.micasaverde.com/index.php/topic,31716.msg256791.html#msg256791

Here is my story about that : http://forum.micasaverde.com/index.php/topic,31716.msg267601.html#msg267601

Could you please explain how did you manage to do it ? You can use "history" command in bash to find all executed commands.

Thanks for your help.

Regards

cbrandlehner commented 8 years ago

Hi @tahitibub I posted a full documentation on my blog: http://chris.brandlehner.at/Brandlehner/cab_blog.nsf/d6plinks/CBRR-A6XQUY

tahitibub commented 8 years ago

@cbrandlehner

Hi Chris,

Thank you very much for that, this is a very helpful explanation.

However, could you add the VERA plugin to your Docker container (I don't manage to do it by myself) : https://www.npmjs.com/package/homebridge-vera

This plugin seems mandatory to operate with Micasaverde "Vera" domotic boxes (http://getvera.com/).

Kind regards,

NB : you can follow our tries to make it work on this new thread http://forum.micasaverde.com/index.php/topic,36131.0.html

Tigo72 commented 8 years ago

@cbrandlehner

Hi Chris, great tutorial on your blog, but i get stuck at the very end. I get to see the docker images, but after the 'run' command, the containers keep stopping immediately. The log says :

--- stdout 23:02:55 Loaded config.json with 0 accessories and 1 platforms. 
stdout 23:02:55 
--- stdout 23:02:55 Loading 1 platforms... 
stdout 23:02:55 /usr/lib/node_modules/homebridge/lib/api.js:88 
stderr 23:02:55  throw new Error(&amp;amp;quot;The requested platform '&amp;amp;quot; + name + &amp;amp;quot;' was not registere 
stderr 23:02:55  ^ 
stderr 23:02:55 Error: The requested platform 'eDomoticz' was not registered by any plugin. 
stderr 23:02:55  at API.platform (/usr/lib/node_modules/homebridge/lib/api.js:88:13)

and so on....

I did use ssh to "npm install -g homebridge-edomoticz" and files are present in /usr/lib/node_modules/homebridge-edomoticz

I am pretty sure my config.json is okay too. Can you give me a hint how to solve this?

Thanks, Tigo

cbrandlehner commented 8 years ago

Hi, every time you start a docker container, all changes made in previous sessions are lost. I usually create a new docker container but you can try using "rerun" instead of "run".

Tigo72 commented 8 years ago

Thanks for your reply Chris. Unfortunately it doesn't work. When I give the run command

docker run -d --net=host -p 51826:51826 -v /volume1/docker/homebridge:/root/.homebridge cbrandlehner/homebridge:0.6-SNAPSHOT

a new docker container is created but that is immediately stopped. Repeating the run command results in yet another container that is stopped, and so on. I have no idea why the container process is killed. Rerunning the container is not even an option, as every button stays gray.

Tigo72 commented 8 years ago

Update: I seem to have made some progress. I updated the node.js package. Seems to have had some influence. Now the configuration is loading but the script is kicking me out because of a problem (missing password) with the Nefit Thermostat. Seems I can fix that...

EDIT: Nope, can't get around the Nefit Easy configuraton. Requires node 4 and up and my Synology doesn't support that. Because of it, I have the easy HTTP running in another Docker container.

cbrandlehner commented 8 years ago

@Tigo72 Yesterday I published a new version that's based on Node 5.x because I wanted to try the mqtt bridge which asks for node 4. It runs on my Synology in docker. https://github.com/cbrandlehner/homebridge-docker

Tigo72 commented 8 years ago

@cbrandlehner

Thanks so much, great work! I got it up and running and it's stable.

Two problems remain in my case. (1) What I cannot figure out is why my plugins are not registered. I keep getting errors such as these:


/usr/lib/node_modules/homebridge/lib/api.js:88 throw new Error("The requested platform '" + name + "' was not registered by any plugin."); ^

Error: The requested platform 'eDomoticz' was not registered by any plugin. at API.platform (/usr/lib/node_modules/homebridge/lib/api.js:88:13) at Server._loadPlatforms (/usr/lib/node_modules/homebridge/lib/server.js:196:45)


It happens with every platform or accessory, except Philips Hue; although Eve or Insteon+ do not recognize accessories, nor do they give me an opportunity to enter the pin. = Problem (2), maybe related to (1)?

If have installed plugins several times using

npm install -g homebridge-edomoticz or similar plugins.

After hours of trying, I do not know how to fix this. Maybe some dependencies are missing, I have no clue...

cbrandlehner commented 8 years ago

@Tigo72 I am afraid the plugins have to be installed in the docker container. I just uploaded a new version 0.8 that contains homebridge-edomoticz You may want to look into https://github.com/cbrandlehner/homebridge-docker and make your own docker container.

Tigo72 commented 8 years ago

@cbrandlehner Great, thanks for your help Chris!

EMCSizl commented 8 years ago

Hi all, came across a strange issue when building my container for Homebridge. My Dockerfile contains the ADD directive to copy my config.json into /root/.homebridge/

ADD config.json /root/.homebridge/config.json

For some unknown reason, the file never actually appears in the container. During the build I can see the add is successful

Step 23 : ADD config.json /root/.homebridge/config.json ---> 5a167031a36e

I even added my own json files in the persist directory which worked perfectly.

Step 21 : ADD AccessoryInfo.CC223DE3CE32.json /root/.homebridge/persist/AccessoryInfo.CC223DE3CE32.json ---> 093b0067282c Removing intermediate container ee65501acec8 Step 22 : ADD IdentifierCache.CC223DE3CE32.json /root/.homebridge/persist/IdentifierCache.CC223DE3CE32.json ---> b276e7ae0e75

I exported the container to a TAR file and extracted the config.json file ok, but every time I start the container it would complain, no config.json.

I got around it by adding the file to /root and then copying the files in place in the run.sh and all works great.

if anyone has any idea why this doesn't work please share. I built the container on my mac and then pushed/pulled it so I figure this was not unique to the Synology but clearly something I am doing since no one else has seen this that I can tell

thanks

cbrandlehner commented 8 years ago

If you use the ADD command, you copy a file within the container. However, if you start the container with the -v parameter, you map a directory into the container which has a higher priority than the files within the container.

So you should either use ADD which I think is unflexible as every change needs that you create a new docker image OR you place the config file outside of the container and map it via -v.

EMCSizl commented 8 years ago

ok, thanks for that. (RTFM) :)