# Image works on Docker but not on Kubernetes

**URL:** <https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190>\
**Category:** General\
**Created:** [5 May 2021 04:08 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190 "2021-05-05T04:08:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [5 May 2021 04:08 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/1 "2021-05-05T04:08:46Z")

</div>

I have a simple Dockerfile:

```auto
FROM nodered/node-red

# Copy package.json to the WORKDIR so npm builds all
COPY package.json .
COPY node-red-static .
COPY defaults .
RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production

# NodeRED configuration
COPY .node-red/settings.js /usr/src/node-red/.node-red/settings.js
COPY .node-red/flows.json /data/flows.json

```

That I turned into an image and run it using:

```auto
docker run -it --rm -p 1880:1880/tcp ghcr.io/myorg/myImage:latest

```

Works like a charm. Now I tried to deploy that to a MicroK8S Kubernetes instance using a deployment

```auto
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodered-deployment
  labels:
    app: core
spec:
  replicas: 2
  selector:
    matchLabels:
      app: core
  template:
    metadata:
      labels:
        app: core
    spec:
      containers:
      - name: core
        image: ghcr.io/myorg/myImage:latest
        ports:
        - containerPort: 1880
        imagePullPolicy: Always
        volumeMounts:
          - name: facility-volume
            mountPath: '/opt/facility/facility.json'
            subPath: facility.json
          - name: core-export
            mountPath: "/export"  
        resources:
          limits:
            memory: "8Mi"
            cpu: "500m"
        envFrom:
        - secretRef:
            name: core-secret    
      imagePullSecrets:
      - name: regcred 
      volumes:
        - name: facility-volume
          configMap:
            name: facility-map
        - name: core-export
          persistentVolumeClaim:
            claimName: export-pv-claim 

```

K8S indicates a successful deployment, but port 1880 is silent.  
So I checked the log of the pod. It contains exactly 2 lines:

```auto
core@0.1.0 start /usr/src/node-red
node-red --settings ./.node-red/settings.js --userDir ./.node-red "--userDir" "/data" 

```

Then I checked `ps -A` and get

```auto
PID USER TIME COMMAND
    1 node-red 0:09 npm
   16 node-red 2:08 node /usr/src/node-red/node_modules/.bin/node-red --settin
   30 node-red 0:00 /bin/sh
   35 node-red 0:00 ps -A

```

Which would indicate, the application is running? (Or stuck?)  
What do I miss?

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [5 May 2021 04:25 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/2 "2021-05-05T04:25:14Z")

</div>

Update: I tried the same with a naked image:

```auto
kind: Deployment
metadata:
  name: red-playground
  labels:
    app: red-playground
spec:
  replicas: 2
  selector:
    matchLabels:
      app: red-playground
  template:
    metadata:
      labels:
        app: red-playground
    spec:
      containers:
      - name: red-playground
        image: nodered/node-red:latest
        ports:
        - containerPort: 1880
        imagePullPolicy: Always 
        resources:
          limits:
            memory: "8Mi"
            cpu: "500m"   
      imagePullSecrets:
      - name: regcred 
---
apiVersion: v1
kind: Service
metadata:
  name: red-service
  labels:
    app: red-playground
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 1880
    protocol: TCP
    targetPort: 1880
  selector:
    app: red-playground
  sessionAffinity: ClientIP

```

There the log says:

```auto
> node-red-docker@1.3.4 start /usr/src/node-red
> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"
5 May 04:21:33 - [info] 
Welcome to Node-RED
===================
5 May 04:21:35 - [info] Node-RED version: v1.3.4
5 May 04:21:35 - [info] Node.js version: v10.24.1
5 May 04:21:35 - [info] Linux 5.8.0-50-generic x64 LE

```

But no luck on port 1880. I must be missing something?

---

<div class="post-metadata">

**Author:** ![NotQuiteAllThere](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@NotQuiteAllThere](https://discourse.nodered.org/u/NotQuiteAllThere)\
**Post date:** [5 May 2021 09:53 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/3 "2021-05-05T09:53:33Z")

</div>

Looks like you might need to use a NodePort instead of a ClusterIP in your service to expose the two node-red replicas outside your cluster (assuming these replicas are on a single node)

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [7 May 2021 06:09 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/4 "2021-05-07T06:09:31Z")

</div>

@NotQuiteAllThere : got an example YAML I can learn from?

---

<div class="post-metadata">

**Author:** ![NotQuiteAllThere](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@NotQuiteAllThere](https://discourse.nodered.org/u/NotQuiteAllThere)\
**Post date:** [12 May 2021 18:01 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/5 "2021-05-12T18:01:27Z")

</div>

```auto
# node-red deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-red-deployment
  labels:
    app: node-red
spec:
  replicas: 1
  selector:
    matchLabels:
      app: node-red
  template:
    metadata:
      labels:
        app: node-red
    spec:
      containers:
      - name: node-red
        image: nodered/node-red:latest
        ports:
        - containerPort: 1880
---
# node-red service
apiVersion: v1
kind: Service
metadata:
  name: node-red-service
  labels:
    app: node-red
spec:
  type: NodePort
  selector:
    app: node-red
  ports:
    - protocol: TCP
      port: 1880
      targetPort: 1880
      nodePort: 30330

```

---

<div class="post-metadata">

**Author:** ![NotQuiteAllThere](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@NotQuiteAllThere](https://discourse.nodered.org/u/NotQuiteAllThere)\
**Post date:** [12 May 2021 18:12 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/6 "2021-05-12T18:12:03Z")

</div>

With the above you'll need access to the latest Node Red image. For minikube:

```auto
minikube cache add nodered/node-red:latest

```

And to access the service, you'll need to get hold of the cluster's ip address. For minikube:

```auto
minikube ip

```

Then to access the cluster use the returned IP address and the port defined in the service (30330 in the service above).

```auto
http://<ip-address-of-cluster>:30330

```

 ![Screenshot 2021-05-12 at 19.07.23](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/2/a2c4218edcfeb41be26916b5c1ef3750463d0df2.png)

Be careful though, kubernetes applications are meant to be stateless so you might lose Node Red data if you don't use persistent volumes for the /data volume. However the above should be a good starting point or useful as a proof-of-concept.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [31 May 2021 12:05 UTC](https://discourse.nodered.org/t/image-works-on-docker-but-not-on-kubernetes/45190/7 "2021-05-31T12:05:36Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
