Deploy ThingsBoard CE as a Monolith on Kubernetes

A simple and lightweight Kubernetes deployment for ThingsBoard CE 3.9.1 using the monolithic Docker image, Traefik ingress, and MQTTS over port 8883.

This guide walks you through deploying the monolithic version of ThingsBoard Community Edition (v3.9.1) on Kubernetes using the official thingsboard/tb-postgres Docker image.


Important Notes

This deployment is:

  • Minimal: single container (tb-postgres)
  • Easy to run: no Kafka, Cassandra, or Redis
  • Not production-ready: uses in-memory queue, no clustering
  • Ideal for: testing, development, personal dashboards, proof-of-concepts

Prerequisites

  • Kubernetes cluster (e.g., EC2, kubeadm)
  • Helm installed
  • cert-manager installed and DNS-01 validated
  • A working ClusterIssuer (e.g., letsencrypt-prod)
  • A TLS cert created with:
  • Common name: thingsboard.maksonlee.com
  • Secret name: thingsboard-tls
  • Cloudflare API key stored as secret (used by cert-manager)
  • Traefik installed (via Helm)

  1. Namespace and PVCs
kubectl create namespace thingsboard
# thingsboard-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: tb-data
  namespace: thingsboard
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: tb-logs
  namespace: thingsboard
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
kubectl apply -f thingsboard-pvc.yaml

  1. Deploy ThingsBoard
# thingsboard.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thingsboard
  namespace: thingsboard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: thingsboard
  template:
    metadata:
      labels:
        app: thingsboard
    spec:
      initContainers:
        - name: fix-perms
          image: busybox
          command: ["sh", "-c", "chown -R 799:799 /data /var/log/thingsboard"]
          volumeMounts:
            - name: tb-data
              mountPath: /data
            - name: tb-logs
              mountPath: /var/log/thingsboard
      containers:
        - name: thingsboard
          image: thingsboard/tb-postgres:3.9.1
          env:
            - name: LOAD_DEMO
              value: "true"
            - name: JAVA_OPTS
              value: "-Xmx1024m -Duser.home=/tmp"
          ports:
            - containerPort: 9090
            - containerPort: 1883
          volumeMounts:
            - name: tb-data
              mountPath: /data
            - name: tb-logs
              mountPath: /var/log/thingsboard
      volumes:
        - name: tb-data
          persistentVolumeClaim:
            claimName: tb-data
        - name: tb-logs
          persistentVolumeClaim:
            claimName: tb-logs
---
apiVersion: v1
kind: Service
metadata:
  name: thingsboard
  namespace: thingsboard
spec:
  selector:
    app: thingsboard
  ports:
    - name: http
      port: 8080
      targetPort: 9090
    - name: mqtt
      port: 1883
      targetPort: 1883
kubectl apply -f thingsboard.yaml

  1. Web Ingress
# thingsboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: thingsboard
  namespace: thingsboard
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - thingsboard.maksonlee.com
      secretName: thingsboard-tls
  rules:
    - host: thingsboard.maksonlee.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: thingsboard
                port:
                  number: 8080
kubectl apply -f thingsboard-ingress.yaml

  1. Add MQTTS Support to Traefik
If you already have Traefik installed (e.g., for HTTPS ingress), you only need to append the following sections to your traefik-values.yaml:
# Add to `ports:` section
  mqtts:
    port: 8883
    expose:
      default: true
    exposedPort: 8883
    protocol: TCP

Then upgrade Traefik:

helm upgrade traefik traefik/traefik \
  -n kube-system -f traefik-values.yaml

  1. MQTTS TCP Ingress
# thingsboard-mqtts-tcp.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: thingsboard-mqtts
  namespace: thingsboard
spec:
  entryPoints:
    - mqtts
  routes:
    - match: HostSNI(`thingsboard.maksonlee.com`)
      services:
        - name: thingsboard
          port: 1883
  tls:
    passthrough: false
    secretName: thingsboard-tls
kubectl apply -f thingsboard-mqtts-tcp.yaml

  1. Test Your Setup

Web UI:

Visit:

https://thingsboard.maksonlee.com

Login with default credentials:

RoleUsernamePassword
System Administratorsysadmin@thingsboard.orgsysadmin
Tenant Administratortenant@thingsboard.orgtenant
Customer Usercustomer@thingsboard.orgcustomer

MQTTS:

mosquitto_pub -d -q 1 -h thingsboard.maksonlee.com -p 8883 --tls-version tlsv1.2 --capath /etc/ssl/certs -u "A1_TEST_TOKEN" -t "v1/devices/me/telemetry" -m '{"temperature":25}'
Client null sending CONNECT
Client null received CONNACK (0)
Client null sending PUBLISH (d0, q1, r0, m1, 'v1/devices/me/telemetry', ... (18 bytes))
Client null received PUBACK (Mid: 1, RC:0)
Client null sending DISCONNECT

Deployment Summary

ComponentStatus
Web UIHTTPS via Traefik
MQTT over TLSPort 8883 exposed
Message QueueIn-memory only
Deployment TypeMonolith (tb-postgres)
Production-ReadyNot recommended

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top