How can I install additional dependencies to the container?

12/20/2021

I've got a nodered server (automation tool) up and running in my cluster. But I would like to add support in nodered for Elasticsearch.

If I were onprem with a physical server I would run npm install node-red-contrib-elasticsearch-jd (and bobs my uncle :-).

But I'm new to kubernetes, how do I do that? With a ConfigMap? The container would also require the npm tool installed I guess.

Any tips?

-- u314
elasticsearch
kubernetes
node-red

3 Answers

12/21/2021

If you want to add something to a running container, you can execute commands in your Pod, the same as you do on the physical server.

kubectl exec -it {target-pod-name} -- npm install node-red-contrib-elasticsearch-jd

However, the above command only adds the package to the container, so when you restart the container, you need the same procedure to install the dependencies again.

If you want to make it permanent, you need to create Dockerfile and re-build an image from the image you use.

Dockerfile:

FROM {your-image}
RUN npm install node-red-contrib-elasticsearch-jd 

Then execute docker build to build a new image. If you use the new image, it should work the same as before, but there is a new dependency installed.

-- Daigo
Source: StackOverflow

12/21/2021

I think there are three good ways to deal with this issue.

First one is to use postStart handler in your pod / deployment file. In your case it will look like this:

...
containers:
  - name: your-pod
    image: your-image
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "npm install node-red-contrib-elasticsearch-jd"]

It will run the command from the command block immediately after a container is started:

Kubernetes sends the postStart event immediately after a Container is started

Example with NGINX deployment with postStart handler to install curl package:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-deployment
spec:
  selector:
    matchLabels:
      app: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "apt update && apt -y install curl"]

Second one it is to run command in the running container:

kubectl exec -it {your-pod-name} -- npm install node-red-contrib-elasticsearch-jd

This is temporary (after a restart there will be no package), if you want this package to be permanent after a restart either add a postStart handler (as explained before) or build a new Docker image (below).

Last one, as suggested in the comments is to build new Docker image from following Dockerfile:

FROM {your-image-name}
RUN npm install node-red-contrib-elasticsearch-jd

Then you can upload newly built image to the registry and pull it from there - if you are using a private registry you need to configure Kubernetes by adding credentials and refer to them in the pod / deployment file.

-- Mikolaj S.
Source: StackOverflow

12/25/2021

First approach should be to use the Palette Manager built into Node-RED to install nodes. You can access this from the menu in the top right hand corner of the editor.

If you have mounted a volume to the /data directory of the container then this should be persistent across a restart of the container.

If you want all instances of the container to have the node pre-installed then you need to extend the Official Node-RED container (or build a totally custom container).

Building a container with the following Dockerfile should work, but if you need to add any native pre-req's it's important to remember the base container is built onto of the Alpine container

FROM nodered/node-red
RUN npm install node-red-contrib-elasticsearch-jd
-- hardillb
Source: StackOverflow