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)
- 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
- 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
- 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
- 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
- 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
- Test Your Setup
Web UI:
Visit:
https://thingsboard.maksonlee.com
Login with default credentials:
Role | Username | Password |
---|---|---|
System Administrator | sysadmin@thingsboard.org | sysadmin |
Tenant Administrator | tenant@thingsboard.org | tenant |
Customer User | customer@thingsboard.org | customer |
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
Component | Status |
---|---|
Web UI | HTTPS via Traefik |
MQTT over TLS | Port 8883 exposed |
Message Queue | In-memory only |
Deployment Type | Monolith (tb-postgres ) |
Production-Ready | Not recommended |