How do I update nodejs on build with Docker Compose?

I am running Node-RED within a container, which is great because it’s so easy to install it on new setups. But on two of them I would like to run a “plug-in” (contrib) that needs nodejs v18 or more, while the image I’m using has 16. I tried this in my docker file to get that working:

      dockerfile_inline: | 
        FROM  nodered/node-red:3.1-debian
        USER root
        RUN apt-get update \
          && apt-get install -y --no-install-recommends iputils-ping sshpass openssh-client curl
        RUN curl -sL | bash
        RUN apt-get install -y nodejs
        USER node-red

So it switches to user root, runs the stuff I already have working, with curl at the end. Then it should run the curl script and finally install nodejs. But I still have 16 after that. Any idea what’s happening here? From the logs it seems like it should have worked, but no. Node-RED still says 16 is installed.

#6 [node-red 3/4] RUN curl -sL | bash
#6 0.704 e[38;5;79m2023-12-31 16:34:18 - Installing pre-requisitese[0m
#6 0.886 Hit:1 buster InRelease
#6 0.887 Hit:2 buster/updates InRelease
#6 0.911 Hit:3 buster-updates InRelease
#6 2.007 Reading package lists...
#6 4.001 Reading package lists...
#6 6.054 Building dependency tree...
#6 6.409 Reading state information...
#6 7.154 ca-certificates is already the newest version (20200601~deb10u2).
#6 7.154 gnupg is already the newest version (2.2.12-1+deb10u2).
#6 7.154 gnupg set to manually installed.
#6 7.154 curl is already the newest version (7.64.0-4+deb10u8).
#6 7.154 0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.
#6 7.543 Hit:1 buster InRelease
#6 7.552 Hit:2 buster/updates InRelease
#6 7.585 Hit:3 buster-updates InRelease
#6 7.670 Get:4 nodistro InRelease [12.1 kB]
#6 8.830 Get:5 nodistro/main arm64 Packages [6613 B]
#6 8.877 Fetched 18.8 kB in 1s (13.3 kB/s)
#6 8.877 Reading package lists...
#6 10.85 e[1;32m2023-12-31 16:34:28 - Repository configured successfully. To install Node.js, run: apt-get install nodejs -ye[0m
#6 DONE 11.1s

#7 [node-red 4/4] RUN apt-get install -y nodejs
#7 0.608 Reading package lists...
#7 2.638 Building dependency tree...
#7 3.008 Reading state information...
#7 3.688 The following NEW packages will be installed:
#7 3.690   nodejs
#7 3.955 0 upgraded, 1 newly installed, 0 to remove and 6 not upgraded.
#7 3.955 Need to get 29.0 MB of archives.
#7 3.955 After this operation, 189 MB of additional disk space will be used.
#7 3.955 Get:1 nodistro/main arm64 nodejs arm64 18.19.0-1nodesource1 [29.0 MB]
#7 6.956 debconf: delaying package configuration, since apt-utils is not installed
#7 7.086 Fetched 29.0 MB in 2s (13.7 MB/s)
#7 7.257 Selecting previously unselected package nodejs.
(Reading database ... 18545 files and directories currently installed.)
#7 7.300 Preparing to unpack .../nodejs_18.19.0-1nodesource1_arm64.deb ...
#7 7.316 Unpacking nodejs (18.19.0-1nodesource1) ...
#7 14.72 Setting up nodejs (18.19.0-1nodesource1) ...
#7 DONE 22.8s

#8 [node-red] exporting to image
#8 exporting layers
#8 exporting layers 5.1s done
#8 writing image sha256:4357024ce3453815fda737a115d65e6764bae142ba60f0ab915771f31e782269 done
#8 naming to 0.0s done
#8 DONE 5.2s

It seems the installation happened and the question is how node-red uses node and how it detects which binary it should use. You probably know about the command “which” which tells you what would be executed if you used the command in the terminal. There is another called “whereis” which tells you where that command or folder can be found (I didn’t know about the folder until today).

whereis node


node: /usr/bin/node /usr/local/bin/node /usr/include/node

So /usr/bin/node is v18 and/usr/local/bin/node is v16. If you don’t have a better idea, you could rename the original node to “node-v16” and create a symbolic link to v18:

mv /usr/local/bin/node /usr/local/bin/node-v16
ln -s /usr/bin/node /usr/local/bin/node

Of course it could break some features if not all.

I think the Node-Red documentation should cover the topic of node updates or additional node installations if it is supported, but you can also find the source code and build your node-red version. That was you can use the official node base image with the correct node version instead of installing an additional node.

I found the links in the image description: Docker
which also includes the node-red forum link as well which I’m sure you know, I just wanted to point out that they may have a better suggestion o support a different node version in the node-red image.

Why not just use the nodered image with the right NodeJS version, like 3.1.3-18 (link)?

1 Like

Perfect!! That’s what I was looking for but somehow didn’t catch it in the readme :slight_smile: So @mastiffen, that is the answer :slight_smile:

@rimelek and @bluepuma77 Thanks, but I was told that for the Pi the Debian image was the one to use. Is the Alpine just as good, then?

I don’t know why it would matter in a container. I know that Docker does not have installation instructions for the 64 bit version of Rasberry Pi and following the debian way is the recommended, but in a container the point is that you can use any type of containers as long as they are based on the same operating system, meaning you run Linux containers on Linux.

On the other hand, @bluepuma77’s link points to a part of the readme where “docker-custom” is mentioned to help with building other images. It looks like there are not many debian variants:, but if alpine isn’t good on RPi (I have no idea why it would be the case, but I don’t know node-red either, shame on me) you can still build your own version of ndoe-red. If that doesn’t wok with the debian based varait either, then my suggestion could be used too, but I would prefer to just use the official images.

I suddenly remembered why I was warned away from Alpine. Some of the hardware doesn’t work correctly with it. But I think I’ll ry to get around this problem by using another way of acheieving what I’m trying to achieve. Thanks for the attempts to help!

Attempts? We suggested multiple solutions. Using one of the alpine based official images was one of them.

I quote some comments:

Have you checked it? Or is there a reason why you can’t build a custom image following this guide:

build new images see docker-custom and the documentation on the Node-RED site here.

It is just a couple of lines and you have a node-red image based on debian with node 18.


git clone
cd node-red-docker/docker-custom
git checkout v$node_red_version
docker build . -f Dockerfile.debian -t "$image_tag" --build-arg NODE_VERSION=18
docker run -d -p 1880:1880 --name "$container_name" "$tag"
docker exec "$container_name" node --version



I didn’t really configure it, but it starts.

I used “localhost” in the image tag, but you could use one that could be pushable to a registry.