How can I ping from a Node-RED container to external host?

I am trying to go Docker Compose on all the stuff I have in my car and my boat, so I can automate updates (stop the containers, prune them all and then pull and restart them). But Node-RED has one thing that gives me grief, the ping. I am using the Debian version of the image because of some other stuff that I need. I first tried the ping node, and just got a “false”, so no contact. Then I tried with an exec node to get more info and I was first told that it couldn’t find the binary ping, so I made that accessible, and then a dependency, libcap.so.2. But of couse it didn’t work.

    volumes:
      - /bin/ping:/bin/ping:ro
      - /usr/lib/arm-linux-gnueabihf/libcap.so.2:/usr/lib/arm-linux-gnueabihf/libcap.so.2:ro

I have set Host to network mode, and I can see that it can get to stuff by using http requests from Node-RED but that didn’t help ping either. I am sure it’s something I just don’t understand of this. Can somebody please enlighten me? :smiley:

DO NOT mount system binaries and libraries to a container. Build your own image using a Dockerfile and install the necessary packages in the image. It is not clear to me why you need to ping the host, but I’m not a node-red user. If you need the ping binary in the Debian container, install the iputils-ping package.

In case of Compose v2 you can do it in a single compose file.

services:
  service_name:
    build:
      dockerfile_inline: | 
        FROM node-red-image-name
        RUN apt-get update \
          && apt-get install -y --no-install-recommends iputils-ping

I haven’t tried so you may need to correct it if I made mistakes. And of course you need a valid parent image name.

Thank you very much for answering! So just to be clear, something like this?

version: "3.7"

services:
  node-red:
    privileged: true
    image: nodered/node-red:3.1-debian
    container_name: Node-RED
    build:
      dockerfile_inline: | 
        FROM node-red-image-name
        RUN apt-get update \
          && apt-get install -y --no-install-recommends iputils-ping
    restart: no
    group_add:
        - "20"
    environment:
      - TZ=Europe/Oslo
    network_mode: host 
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    volumes:
      - /home/pi/Node-RED:/data
      - /home/pi/Sikkerhetskopier:/home/pi/Sikkerhetskopier
      - /bin/ping:/bin/ping:ro
      - /usr/lib/arm-linux-gnueabihf/libcap.so.2:/usr/lib/arm-linux-gnueabihf/libcap.so.2:ro

And the reason is simply that if one or more of my network devices are pingable, the network is still up and running, and a specific problem needs a reboot. :slight_smile:

Please, don"t copy-paste my code snippet. If the concept of a Dockerfile is still new to you, I recommend searching for it in the official documentation or basically anywhere on the internet :slight_smile: YOu need the node red image name after the FROM instruction instead of my placeholder and since you are building an image, you must not set the “image:” parameter to the same value. Otherwise you will override the original tag and next time add more and more layers to the same image when you rebuild it.

And mounting the ping binary and the library is still a bad idea not to mention that it is completely unneccessary now :slight_smile:

Sorry, my mistake. Of course. :roll_eyes: I have been using Docker Compose for a while, but more advanced stuff is a bit over my head yet. Just to make shure, why is it unnecessary to mount the ping library? I need that ping for a check of devices on my net that can only be pinged, thy won’t react to a http request or similar.

So I corrected it as your instructions:

version: "3.7"

services:
  node-red:
    build:
      dockerfile_inline: | 
        USER root
        FROM  nodered/node-red:3.1-debian
        RUN apt-get update \
          && apt-get install -y --no-install-recommends iputils-ping
        USER pi
    image: nodered/node-red:3.1-debian
    privileged: true
    container_name: Node-RED
    restart: no
    group_add:
        - "20"
    environment:
      - TZ=Europe/Oslo

    network_mode: host 
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    volumes:
      - /home/pi/Node-RED:/data
      - /home/pi/Sikkerhetskopier:/home/pi/Sikkerhetskopier

And with this new attempt, it actually works! I had to set user to root and then back to pi to avoid a lock error (Could not open lock file /var/lib/apt/lists/lock), but with that I got the right answer back! Security is not a concern, this boat Pi is not open to anything but my internal network. EDIT: I thought that the built-in Ping node in Node-RED didn’t work, but it had to be removed and reinstalled with the ping framework installed. Thanks again!

image

You should use build or image, as one will overwrite the other.

Ah, thanks! I misunderstood, I thought that the build should be before image. Because when I do this without image, this happens:

pi@Hytte-Pi:~/Docker-Compose/Nodered $ sudo docker compose up
[+] Building 1.0s (2/2) FINISHED                                                                       docker:default
 => [node-red internal] load build definition from Dockerfile                                                    0.4s
 => => transferring dockerfile: 173B                                                                             0.0s
 => [node-red internal] load .dockerignore                                                                       0.8s
 => => transferring context: 2B                                                                                  0.0s
failed to solve: no build stage in current context

If image is there as well, it completes download, pull and build, and the ping works.

Edit: Found the problem, after a bit (well, a lot) of Googling and experimenting. FROM had to be before USER root. Now it works with no more image definitions. :grin:

Because you install everything in the container. More precisely in the image which the container will be based on. Volumes and bind mounts are for data, not fo binaries or libraries. You can’t even be sure that the libraries on the host will be compatible with the system in the container. It could be a different version and you get an unexpected result. I’m not saying you can never mount binaries, but most of the time it is a bad idea to mount something from the system binaries. You can build a binary locally which includes everything in that single binary so it can run in an empty container. (FROM scratch). But this is not that case.

FROM is always the first instruction except when you need a build argument and use the variable in the FROM instruction like this:

ARG BASE_VERSION=1.0
FROM myimage:${BASE_VERSION}

Everything you want to be a part of the new image must be after the FROM instruction

@rimelek Thank you again! That of course makes perfect sense. :smiley: I now have it up and running with both ping, sshpass and open-ssh installed in the build. That means taht I can ping the devices to see if everything works and then restart the host and another Pi on the network with SSH if the network is down. Very cool!