Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / IoT

IoT Starter Raspberry Pi Compose

5.00/5 (2 votes)
13 Feb 2018CPOL3 min read 13.7K  
Compose microservices at Raspberry Pi with Linux & .NET Core to start an IoT initiative right now

Introduction

This project develops microservices based on API First Design, targeting Raspberry Pi with Linux. In order to speed up IoT initiatives, the IoT starter evolves a customizable, ready to run, Thing device. A comprehensive path is provided by the episodes listed below:

  1. IoT.Starter.Pi.Core: At this project targeted to Raspberry Pi with Linux, the API First Design strategy is used to develop an ASP.NET Core Web Server automatically generated by SwaggerHub.

  2. IoT.Starter.Pi.Thing: IoT Starter Pi Thing includes the basic stuff to be included in any Thing, which means future projects are expected to start from here.

  3. IoT.Starter.Pi.Lirc: This mission provides infrared (IR) output capability to IoT.Starter.Pi.Thing.

  4. IoT.Starter.Pi.Lumi: At this complement of the third part, the API and corresponding web service is extended to consider IR remotes and their respective codes.

As we experienced at previous episodes, after each change on the API, SwaggerHub automatically generates updated code for home-web containing corresponding web service. The Thing has also home-ui and nginx-proxy images, handling respectively user interface and SSL security. They all run in separate docker containers, cooperating and sharing common resources with a host powered by Raspberry Pi with Linux & .NET Core.

The solution builds fast and efficiently at a speedy x64 machine equipped with Windows 10 and Visual Studio 2017. The docker-compose build command follows the steps from each dockerfile, generating the images below that are finally pushed to DockerHub registry:

At Raspberry Pi side, we experienced that running each container manually is still somewhat time consuming. The mission now is to take IoT.Starter.Pi.Thing a step further with docker-composer up command. The same docker-compose.yml file, used to orchestrate the build phase at x64 machine, is reused to load images, create containers, establish relationships, and run them all at Raspberry Pi side.

Installing docker-composer

Please note that installing docker is not enough to run docker-compose at RPI, as we can check below:

pi@zuni:~ $ docker version
Client:
 Version:       18.02.0-ce
 API version:   1.36
 Go version:    go1.9.3
 Git commit:    fc4de44
 Built: Wed Feb  7 21:24:08 2018
 OS/Arch:       linux/arm
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:      18.02.0-ce
  API version:  1.36 (minimum version 1.12)
  Go version:   go1.9.3
  Git commit:   fc4de44
  Built:        Wed Feb  7 21:20:13 2018
  OS/Arch:      linux/arm
  Experimental: false

pi@zuni:~ $ docker-compose version
-bash: docker-compose: command not found

The easiest way to install docker-compose at RPI would be using the command:

sudo apt-get install docker-compose

According to log below, this path results on docker-compose version 1.8.0 being installed at RPI:

pi@zuni:~ $ sudo apt-get install docker-compose
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libyaml-0-2 python-backports.ssl-match-hostname python-cached-property 
  python-cffi-backend python-chardet python-cryptography python-docker 
  python-dockerpty python-docopt

...

The following NEW packages will be installed:
  docker-compose libyaml-0-2 python-backports.ssl-match-hostname 
  python-cached-property python-cffi-backend python-chardet 
  python-cryptography python-docker python-dockerpty
  python-docopt python-enum34 python-funcsigs python-functools32 
  python-idna python-ipaddress python-jsonschema python-mock 
  python-openssl python-pbr python-pkg-resources
  python-pyasn1 python-requests python-setuptools python-six 
  python-texttable python-urllib3 python-websocket python-yaml python3-pkg-resources
0 upgraded, 29 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,860 kB of archives.
After this operation, 8,564 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

...  

Setting up python-openssl (16.2.0-1) ...
Setting up python-docker (1.9.0-1) ...
Setting up docker-compose (1.8.0-2) ...

pi@zuni:~ $ docker-compose version
docker-compose version 1.8.0, build unknown
docker-py version: 1.9.0
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.1.0f  25 May 2017

Unfortunately, this old version has issues with latest RPI binaries and is not reliable. If it is already installed, you can remove it, as shown below:

pi@zuni:~ $ sudo apt-get remove docker-compose
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libyaml-0-2 python-backports.ssl-match-hostname python-cached-property 
  python-cffi-backend python-chardet python-cryptography python-docker 
  python-dockerpty python-docopt
  python-enum34 python-funcsigs python-functools32 python-idna 
  python-ipaddress python-jsonschema python-mock python-openssl 
  python-pbr python-pkg-resources python-pyasn1
  python-requests python-setuptools python-six python-texttable 
  python-urllib3 python-websocket python-yaml python3-pkg-resources
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  docker-compose
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 403 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 35540 files and directories currently installed.)
Removing docker-compose (1.8.0-2) ...
Processing triggers for man-db (2.7.6.1-2) ...

Considering that docker-compose is definitely needed, JC Berthon published a post describing a"easy way" to build it for yourself. I tried it successfully with a RPI 2 model B, and after a long run, the latest docker-compose was built at RPI. The binary file generated was added to home/Docker folder in the project repository.

Next step is to copy the new docker-compose binary to /usr/local/bin and adjust its settings, as shown below:

$ cp docker-compose /usr/local/bin
$ chown root:root /usr/local/bin/docker-compose
$ chmod 0755 /usr/local/bin/docker-compose

$ ls -l /usr/local/bin
total 7052
-rwxr-xr-x 1 root root 7218664 Feb 12 19:06 docker-compose

Finally, confirm which docker-compose version is installed:

pi@lumi:~ $ docker-compose version
docker-compose version 1.19.0-rc2, build dfcb02c
docker-py version: 2.7.0
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

A known issue is that this same binary with RPI Zero returns error. Further checks are necessary to figure out what happens in this case.

Operation with docker-compose

As shown by Viktor Adam in his tutorial, the docker-compose.yml file inside Git repository allows a basic automation to update the microservices whenever something changes.

$ cd /to/your/cloned/folder
$ git pull
$ docker-compose pull
$ docker-compose up -d

The IoT.Starter.Pi.Thing repository is cloned to a RPI folder, as shown below:

git clone git@github.com:josemotta/IoT.Starter.Pi.Thing.git

Now, pulling the latest images from DockerHub is very simple with docker-compose pull:

docker-compose -f lumi-compose.yml pull

Please see at the live action below that all three images are being updated to latest version stored at DockerHub:

root@lumi:~/IoT.Starter.Pi.Thing/home# docker-compose -f lumi-compose.yml pull
Pulling home.ui (josemottalopes/home-ui:latest)...
latest: Pulling from josemottalopes/home-ui
0d9fbbfaa2cd: Already exists
b015fdc7d33a: Already exists
60aaa226f085: Already exists
01963091a185: Already exists
63ffb7955a88: Pull complete
b0ac7ac16eca: Pull complete
Digest: sha256:784b490276b9402cd276f2c211223041779983ac2fdc8ff25b775df6717028cb
Status: Downloaded newer image for josemottalopes/home-ui:latest
Pulling io.swagger (josemottalopes/home-web-ir:latest)...
latest: Pulling from josemottalopes/home-web-ir
0d9fbbfaa2cd: Already exists
b015fdc7d33a: Already exists
60aaa226f085: Already exists
01963091a185: Already exists
f5f67e021814: Pull complete
b640e21d6d61: Pull complete
b81fd5b12fb6: Pull complete
b0409530900f: Pull complete
6e417e6af42e: Pull complete
db68a213ab98: Pull complete
9d099602a010: Pull complete
0ff2feee3ab1: Pull complete
Digest: sha256:b378ca3b49b49e9e14111cf165eaf182ffd97b8f8c8720722cebde13a2ed13e8
Status: Downloaded newer image for josemottalopes/home-web-ir:latest
Pulling ssl.proxy (josemottalopes/nginx-proxy:latest)...
latest: Pulling from josemottalopes/nginx-proxy
cd8b673adb84: Already exists
db611fab629f: Already exists
6fa9759daa34: Already exists
cff4b2a22797: Pull complete
1a7a23dc7a01: Pull complete
5bedaf887e96: Pull complete
54c0a006ff47: Pull complete
Digest: sha256:3a57fb01ca10858cbfc7f1b78e7fc4ea33d772a5d4ead67ff9dcbc84b24a417d
Status: Downloaded newer image for josemottalopes/nginx-proxy:latest

Just one command more is necessary to create and start all three containers:

docker-compose -f lumi-compose.yml up -d

Please see the log below:

root@lumi:~/IoT.Starter.Pi.Thing/home# docker-compose -f lumi-compose.yml up -d
Creating home-web-ir ... done
Creating home-web-ir ...
Creating home-ui ...

root@lumi:~# docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                            NAMES
a45f1330c167        josemottalopes/home-web-ir   "dotnet IO.Swagger.d…"   23 minutes ago      Up 23 minutes       0.0.0.0:32779->5010/tcp          home-web-ir
24b675650f1a        josemottalopes/home-ui       "dotnet Home.UI.dll"     23 minutes ago      Up 23 minutes       0.0.0.0:32777->80/tcp            home-ui
dbb14cc24bf2        josemottalopes/nginx-proxy   "nginx -g 'daemon of…"   23 minutes ago      Up 23 minutes       80/tcp, 0.0.0.0:32778->443/tcp   ssl-proxy

To stop and remove all containers from memory is also very simple:

docker-compose -f lumi-compose.yml down

The results are shown below with all three images stopped and removed:

root@lumi:~/IoT.Starter.Pi.Thing/home# docker-compose -f lumi-compose.yml down
Stopping home-web-ir ... done
Stopping home-ui     ... done
Stopping ssl-proxy   ... done
Removing home-web-ir ... done
Removing home-ui     ... done
Removing ssl-proxy   ... done

root@lumi:~/IoT.Starter.Pi.Thing/home# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Please note that lumi-compose.yml was used above to deal with infrared version of IoT starter. If you don´t need infrared support and Lirc to be installed, please use thing-compose.yml file instead and respective commands would be:

# pull latest changes at DockerHub
docker-compose -f thing-compose.yml pull

# load and start all three docker images
docker-compose -f thing-compose.yml up -d

# stop and remove containers from memory
docker-compose -f thing-compose.yml down

Conclusion

The IoT.Starter.Pi.Thing repository was revised with latest improvements and is ready for starting right now your IoT initiatives.

Have fun!

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)