apiVersion: v1 kind: Namespace metadata: name: automation --- # 1. LONGHORN STORAGE FOR NODE-RED FLOWS & USER PALETTE NODES apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nodered-data-pvc namespace: automation spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi --- # 2. LONGHORN STORAGE FOR ZIGBEE2MQTT PAIRING DATA AND DEVICE CONFIGS apiVersion: v1 kind: PersistentVolumeClaim metadata: name: zigbee2mqtt-data-pvc namespace: automation spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 2Gi --- # 3a. MOSQUITTO LOCAL NETWORK LISTENER CONFIGURATION apiVersion: v1 kind: ConfigMap metadata: name: mosquitto-config namespace: automation data: mosquitto.conf: | listener 1883 0.0.0.0 allow_anonymous true --- # 3b. LIGHTWEIGHT ECLIPSE MOSQUITTO MQTT BROKER apiVersion: apps/v1 kind: Deployment metadata: name: mosquitto namespace: automation spec: replicas: 1 selector: matchLabels: app: mosquitto template: metadata: labels: app: mosquitto spec: containers: - name: mosquitto image: docker.io/library/eclipse-mosquitto:2.0.18 ports: - containerPort: 1883 resources: requests: memory: "16Mi" cpu: "10m" limits: memory: "64Mi" cpu: "100m" volumeMounts: - name: config mountPath: /mosquitto/config/mosquitto.conf subPath: mosquitto.conf volumes: - name: config configMap: name: mosquitto-config --- # 4. NODE-RED RUNTIME CORE DEPLOYMENT apiVersion: apps/v1 kind: Deployment metadata: name: node-red namespace: automation spec: replicas: 1 selector: matchLabels: app: node-red template: metadata: labels: app: node-red spec: securityContext: fsGroup: 1000 runAsUser: 1000 containers: - name: node-red image: docker.io/nodered/node-red:4.0.2 ports: - containerPort: 1880 env: - name: TZ value: "Europe/London" - name: NODE_RED_ENABLE_PROJECTS value: "false" resources: requests: memory: "125Mi" cpu: "50m" limits: memory: "512Mi" cpu: "500m" volumeMounts: - name: nodered-storage mountPath: /data volumes: - name: nodered-storage persistentVolumeClaim: claimName: nodered-data-pvc --- apiVersion: v1 kind: Service metadata: name: node-red-svc namespace: automation spec: ports: - port: 1880 targetPort: 1880 selector: app: node-red --- # 5. NODE-RED INGRESS ROUTING WITH WEBSOCKET UPGRADES FOR THE CANVAS apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nodered-ingress namespace: automation annotations: cert-manager.io/cluster-issuer: "letsencrypt-production" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" spec: ingressClassName: nginx tls: - secretName: nodered-tls-secret hosts: - nodered.needlestack.boo rules: - host: nodered.needlestack.boo http: paths: - path: / pathType: Prefix backend: service: name: node-red-svc port: number: 1880 --- # 6. ZIGBEE2MQTT TRANSLATION CORE DEPLOYMENT apiVersion: apps/v1 kind: Deployment metadata: name: zigbee2mqtt namespace: automation spec: replicas: 1 selector: matchLabels: app: zigbee2mqtt template: metadata: labels: app: zigbee2mqtt spec: # 👇 ADD THIS SECLAYER BLOCK TO REFIX VOLUME OWNERSHIP 👇 securityContext: fsGroup: 1000 runAsUser: 1000 containers: - name: zigbee2mqtt image: docker.io/koenkk/zigbee2mqtt:1.41.0 # 👇 ADD THIS PORTS BLOCK UNDER THE IMAGE 👇 ports: - containerPort: 8080 name: frontend env: - name: TZ value: "Europe/London" - name: ZIGBEE2MQTT_CONFIG_MQTT_SERVER value: "mqtt://mosquitto-svc:1883" # 🌐 NETWORKING LINKAGE FOR YOUR ENET DONGLE-M - name: ZIGBEE2MQTT_CONFIG_SERIAL_PORT value: "tcp://192.168.1.145:6638" # 👈 FIXED: Uses the local hostname - name: ZIGBEE2MQTT_CONFIG_SERIAL_ADAPTER value: "ember" # 👈 FIXED: Matches the recommended driver - name: ZIGBEE2MQTT_CONFIG_ADVANCED_HOMEASSISTANT value: "true" # 👇 ADD THIS LINE TO TURN ON THE WEB ENGINE 👇 - name: ZIGBEE2MQTT_CONFIG_FRONTEND value: "true" resources: requests: memory: "50Mi" cpu: "10m" limits: memory: "256Mi" cpu: "300m" volumeMounts: - name: zigbee2mqtt-storage mountPath: /app/data volumes: - name: zigbee2mqtt-storage persistentVolumeClaim: claimName: zigbee2mqtt-data-pvc --- # 7. ZIGBEE2MQTT DASHBOARD NETWORK SERVICE apiVersion: v1 kind: Service metadata: name: zigbee2mqtt-frontend-svc namespace: automation spec: ports: - port: 8080 targetPort: 8080 selector: app: zigbee2mqtt --- # 8. ZIGBEE2MQTT SECURE INGRESS ROUTING apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: zigbee2mqtt-ingress namespace: automation annotations: cert-manager.io/cluster-issuer: "letsencrypt-production" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/ssl-redirect: "true" # Mandatory for real-time log streaming and pairing maps to stay open nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" spec: ingressClassName: nginx tls: - secretName: zigbee-tls-secret hosts: - zigbee.needlestack.boo rules: - host: zigbee.needlestack.boo http: paths: - path: / pathType: Prefix backend: service: name: zigbee2mqtt-frontend-svc port: number: 8080