gpbenton / engMQTTClient

MQTT client for Energenie ener314-rt board running on a raspberry Pi
MIT License
21 stars 10 forks source link

When running in docker container, no output, not functioning? #25

Closed DrHoneyBear closed 4 years ago

DrHoneyBear commented 4 years ago

Hi mate, fantastic work, don't know how you figured out the protocol and states/topics + RF work. Well done.

So, I am creating a build script that creates a native docker container for a linux based env, should work on any arch. I have the build working and the image created. It works fine on my host Debain buster, but when built in a docker env , when I run up ./engMQTTClient (having set LD_LIBRARY_PATH), nothing happens. Something is preventing it running correctly and it is not listening on 1883/tcp either. There are no logs created and no stdout/stderr.

I've seen this behaviour if the LD_LIBRARY_PATH isn't set , or some lib is missing. But this is all ok in the docker. I was wondering what I could do in the source to enable more debugging to stdout? I mean, it just runs but no output whatsoever.

Once i get this working at runtime, I will provide you with the Dockerfile and docker-compose.yaml , from which your users can download, run, and have a fully functioning docker container on their system, connected and listening on the host machine at default 1883/tcp and localhost - but this can be changed at docker build time by user if needed.

However, at tho mo, I just can't get the client to output anything so I need to debug. Ideas?

TIA

gpbenton commented 4 years ago

Hi, the quick answer to your stdout question is that logging is done through the log4c library and the configuration is described here http://log4c.sourceforge.net/#installation It looks like the default is to print to stderr rather than stdout, which may be your problem.

The other thing that immediately came to mind is to check that the container has permission to access the gpio. There is normally a -dev option to the docker run command, but I've never tried it with the Pi gpio, so I don't know any details.

But I'm curious as to some of your other comments. engMQTTClient is a MQTT client, so it doesn't listen on any port. It connects to a broker (which by default will be listening on port 1883), but that may be from any user port.

How are you proposing to make the options configurable? I think you can use the ENTRYPOINT directive in the Dockerfile as the engMQTTClient command and use the CMD as the options to it to avoid the user having to rebuild the image in order to change options.

And BTW, I didn't figure out much with the RF side, I just used the example code supplied by Energenie and tacked on the MQTT client code. No big deal really.

DrHoneyBear commented 4 years ago

Hi Yes. the CMD/ENTRYPOINT is how I have approached it. The docker is running with --privileged arg so can access all /dev*

BUT

and this is incredibly humilliating but when you mentioned gpio I thought OMG.My host is WSL on Win10 and NOT the Raspberry PI. OMG !

Anyway, progress , but I'm getting : [stderr] 20200504 09:33:38.738 CRIT MQTTClient- Unable to connect: 14 mosquitto is running on localhost 1883/tcp

I'm not a fan of log4c , far better loggers , rather useless if debug is never used as is the case in the default setup. Changing it has no impact so I never use it. Aside this makes makes debugging your client rather difficult. Also, not sure what the purpose of the debug script is, it doesn't add any debug [to this instance]. I suspect the OEM code uses log4c so you just followed along?

EDIT: Fixed. Docker issue. Modified docker-compose.yaml and Dockerfile. Now working on PI running two simple containers: mosquitto in one container , and engMQTTClient in another. Will now test with HA and Openhab containers.

DrHoneyBear commented 4 years ago

Hi Graham,

All sorted ! Running perfectly in a docker container with OH and HA, either running natively or within their respective containers.

Requires packages:

In terms of execution: When the service is started , the docker image is built from all sources as per your README and container is brought up using docker-compose. First run will take some time as the image is constructed. This has the benefit of not explicitly coupling container to a particular O/S or arch. Of course, implicitly there may be src or package incompatibilities , but here I am presuming your build instructions would change - if needed - or the OEM code/build would differ. Subsequent starts are immediate [provided deps not invalidated by user actions]. When the service is stopped, the container is brought down and removed.

In terms of logging: Default is stderr redirected to stdout redirected out of the container and into syslog on the host. So journalctl can be used to view/manage/set/nullify the output of the container execution. Standard logrotate applies.

O/S: Clearly this install presumes a SystemV based *inux O/S such as Ubuntu, Debian,... This may need developing for other O/S.

Security: This basic 1st release setups a host network so all ports accessible although clearly default is 1883/tcp. No other security features removed/added. So a fairly generic basic image for the purpose of installing on a *inux target.

Future: The paradox is that by providing a self building image, I have perhaps digressed from the docker ethos of having prebuilt images targeted at specific O/S environments. Maybe I should build a set of images based on a layer0 ubuntu, debian, fedora, cents etc? What's your view on this?

Once this is refined , I will look at providing this as a HA Integration that can be added via HACS.

So, next Qstn.. How do you want me to package this. I was going to setup a git repo but it is literally just 6 files:

docker-compose.yaml
Dockerfile
energenie-mqtt-client.service
install.sh
run.sh
stop.sh

The install.sh simply installs the 4 docker management files to /opt/energenie_mqtt_client/ and the service unit file into /etc/systemd/system/. It then prints a simple usage instruction on how to run/stop the service.

I haven't included any config elements in the docker files because the service unit file provides the configuration in terms of how to run/stop the docker, using [currently] a run.sh and stop.sh within the /opt/energenie_mqtt_client dir , which the user can configure if needed.

I guess you could try it out - how would you like to proceed ? Darren

gpbenton commented 4 years ago

If you can send me a pull request with all the files in a /docker directory, that would be fine. I have been intending to move my board to my pi3 this summer, while the heating isn't used, so I can try it out then Thanks Graham

gpbenton commented 4 years ago

Docker containers up and running on my system.

Thanks Graham