A Docker container can be used to run a node-RED server on a PLCnext device. Although the other method described here is a little faster. The use of OCI containers comes with some advantages. For example when repeatedly using the same packages for an application it can be useful to build a standard image and just download it from Docker hub. Docker can also be used to start and stop the node-red server when we want to.
This blog will explain just that. First I’ll guide you trough the installation process of Docker and we’ll check the installation. We’ll build a custom image with packages of to our liking pre-installed with a Dockerfile and create a container from our freshly created image. Finally we’ll make sure our container will start on boot of the controller and push our image to Dockerhub.
Installation of the Balena – engine
I lied a bit when I said Docker containers can be used to run a node-RED runtime on a PLCnext device. As you’ll see we use the Balena-engine as an engine to run containers, more specifically we’ll use OCI (Open Container Initiative) containers. Wrestling trough the nomenclature would bring us way to far for a Makersblog, but in the further reading section at the end of this blog I’ve added some links for those who are interested.
The installation procedure is rather easy and can be found here for full reference, but for practicality reasons the commands are also given in the next section.
Make sure you’re logged in as a root user, to create a new root password type the following command in the shell and type your admin password followed by two times the new root pass.
sudo passwd root
Login as root user by typing su followed by your newly created password.
Clone the git repository and go to the new folder
git clone https://github.com/PLCnext/Docker_GettingStarted.git
Make the setup script executable and execute said script.
chmod +x setup.sh
Getting internet acces from your Containers
Sometimes during the installation the nft tables get set up wrong. Luckily this is an easy fix.
The full reference guide can be found here but a short description of the progress is given below.
In your shell type
The configuration of your network interfaces pops up. One of them named Balena, take note of the Inet adress of this interface.
It should be something like this:
Enter the following command in your shell and compare the Inet adress received in the previous step with the second line in the script.
The two addresses should be the same, if so you can go to the next section.
If not, cast the next command in your shell and change the address on the second line to match the one received by ifconfig.
Stop and start the balena-engine-daemon to reload the nft tables.
My first container
To download your first container use the next command, the flags will be explained later on don’t worry about them now.Now we’ll download a node-red container without costum packages. If you don’t need costum packages you can stop here and browse to port 1880 of the controller.
balena-engine run -d -p 1880:1880 --name nodered --restart always nodered/node-red
The arm32v7/debian image used in the previous section was downloaded from Docker Hub.
Docker Hub is essentially a place where container images are gathered and can be easily downloaded from.
I can recommend the organization arm32v7, this organization creates images compatible with the architecture of the AXC F 2152.
The node-red organization has created an images compatible with the AXC F 2152, we’ll use this image in the next section but first I like to mention that if you’ll use containers a lot you should create an account on Docker Hub and use its repositories. You’ll get nearly unlimited public repositories and one private repository when you create a free account. I resisted to use Docker Hub for a while, but it has cost me a lot of time.
In the last section of this blog i will flatten the learning curve of using Docker Hub a bit by showing how to login re-tag an image an push an image to Docker Hub.
A docker file is in a sense the recipe for an docker image. In this blog we’ll use a Dockerfile to create our own node-red image, with the packages we need installed.
The first line of a Dockerfile is almost always the FROM command. With this command we define a base image from where we’ll build our own image.
After the FROM statement, we start building our image. There are a lot of possible commands that can be used in a Dockerfile but here we’ll use only RUN.
A Dockerfile reference link is provided in the further readings section.
The RUN statement will execute the command that follows inside the container that we are building.
So to install a new package, for example the SNMP package we state: RUN
npm install node-red-node-snmp
After the theory, let’s build a Dockerfile. Hopefully, you’re still in a SSH session (make sure you’re back on the AXC F 2152 and not in the debian contain from two sections ago!).
You can create the Dockerfile with nano and copy pasting the contents into the new file. save (ctrl + s) and exit (ctrl + x).nano Dockerfile
RUN npm install node-red-node-snmp
Now it’s time to build our new image!
balena-engine build . --tag myimage
When you recieved the message that the images was tagged succesfully, you’ve build your first image!
To see the image you just build use the command: balena-engine images
Running our new image
Finaly, we are ready to run our image and create a container from it!
Cast the following command in the shell to run the container interactively.
Interactively means that we can see in the terminal what’s going on inside the container.
The opposite is detached, marked with the flag -d
balena-engine run -it -p 1880:1880 --name nodered myimage
To exit the container and keep it running use ctrl + p ctrl +q
When you browse to the IP-address of the controller followed by port 1880 the node red environment shows and we see snmp package installed!
Starting the image on boot and a primer on docker run flags
It is unpractical to boot the container manually every time the AXC F 2152 gets restared. Luckely we can tell Docker to start it for us, and it is easy to!
Just use command listed below. This is also the time to get a better understanding of the docker flags used. For starters, a flag is something we give after the command and starts with either – or –.
Until now we’ve seen only -it, to run a container interactively and -d to run a container detached (in the background).
The flag -p maps the port of the container to the port of the host. First the the portnumber of the host is stated then the portnumber of the container.
We can give the container a name with the –name flag. This name will be shown when u use balena-engine ps, to list all active containers or balena-engine ps -a to list all containers.
When no –name flag is used the balena-daemon will assign a random name to the container.
And last but not least, a restart policy can be assigned to a container with the –restart flag.
The possible settings can be found in the reference link listed in the further readings.
For now –restart always will do the trick! Our command will be:
balena-engine run -it -p 1880:1880 --name nodered --restart always myimage
Pushing to Docker hub
When you wan’t to use your image on different controllers. It’s an good idea to upload your image to Docker Hub.
On the premise that you already have an account and created a docker repository we’ll continue. First we’ll need to login to our account. This can be done by typing balena-engine login followed by your username and password. Now it is possible to download images from private repositories and to push your image to Docker hub.
To push your image to Docker hub it is important to get the name right. When I’ve made a repository myrep and my user account is myaccount the name of the image should be myaccount/myrep.
When you did not name it like that when building the image, you have to re-tag the image by using balena-engine tag oldimagetag newimagetag. In our case this would be:
balena-engine tag myimage myaccount/myrep
When nothing more is defined it well get the label latest. It is possible to at a lable adding a : and a label name. For example:
balena-engine tag myimage myaccount/myrep:alabel
The only thing left is pushing our image to Docker hub with the command:
balena-engine push myaccount/myrep