This guide applies to bare-metal setups only. If you’re running ThingsBoard on Kubernetes, refer to your ingress controller (e.g. Traefik or NGINX) for SSL termination.
Although ThingsBoard officially supports SSL for both HTTP and MQTT, I chose not to configure SSL directly inside ThingsBoard.
The reason is certificate renewal: Let’s Encrypt certs expire every 90 days. If SSL is handled by ThingsBoard itself, each renewal would require a server restart, causing downtime and potential telemetry loss from connected IoT devices.
Pre-requisite
Install ThingsBoard CE 4.0.1 on bare metal first:
Install ThingsBoard CE 4.0.1 on Bare-Metal Ubuntu 24.04
This sets up:
- ThingsBoard HTTP endpoint:
localhost:8080
- MQTT broker:
localhost:1883
What You’ll Achieve
Protocol | Public Port | SSL Terminated | Forwarded To |
---|---|---|---|
HTTPS | 443 | HAProxy | 127.0.0.1:8080 |
MQTTS | 8883 | HAProxy | 127.0.0.1:1883 |
Domain: thingsboard.maksonlee.com
(managed in Cloudflare)
- Install HAProxy + Certbot
sudo add-apt-repository ppa:vbernat/haproxy-3.0 -y
sudo apt-get install haproxy=3.0.\*
sudo apt install certbot python3-certbot-dns-cloudflare -y
- Create Cloudflare API Token
- Go to: Cloudflare API Tokens
- Use the “Edit zone DNS” template
- Restrict it to your domain
- Save the token securely
Create the credential file:
mkdir -p ~/.secrets/certbot
nano ~/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
chmod 600 ~/.secrets/certbot/cloudflare.ini
- Issue the Certificate
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
-d thingsboard.maksonlee.com
- Prepare Cert for HAProxy
sudo mkdir -p /etc/haproxy/certs
sudo bash -c 'cat /etc/letsencrypt/live/thingsboard.maksonlee.com/fullchain.pem \
/etc/letsencrypt/live/thingsboard.maksonlee.com/privkey.pem \
> /etc/haproxy/certs/thingsboard.maksonlee.com.pem'
sudo chmod 600 /etc/haproxy/certs/thingsboard.maksonlee.com.pem
- Configure HAProxy
Edit /etc/haproxy/haproxy.cfg
, add following
# HTTPS (443 -> ThingsBoard HTTP 8080)
frontend https-in
bind *:443 ssl crt /etc/haproxy/certs/thingsboard.maksonlee.com.pem
mode http
option httplog
default_backend thingsboard-http
backend thingsboard-http
mode http
server tb-ui 127.0.0.1:8080 check
# MQTTS (8883 -> MQTT 1883)
frontend mqtts-in
bind *:8883 ssl crt /etc/haproxy/certs/thingsboard.maksonlee.com.pem
mode tcp
option tcplog
default_backend thingsboard-mqtt
backend thingsboard-mqtt
mode tcp
server tb-mqtt 127.0.0.1:1883 check
- Start HAProxy
sudo systemctl restart haproxy
Verify:
https://thingsboard.maksonlee.com
mqtts://thingsboard.maksonlee.com:8883
(IoT devices)
- Auto-Renew Certificate and Reload HAProxy
Create deploy hook:
sudo vi /etc/letsencrypt/renewal-hooks/deploy/haproxy-reload.sh
#!/bin/bash
DOMAIN="thingsboard.maksonlee.com"
cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem \
/etc/letsencrypt/live/$DOMAIN/privkey.pem \
> /etc/haproxy/certs/$DOMAIN.pem
chmod 600 /etc/haproxy/certs/$DOMAIN.pem
systemctl reload haproxy
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy-reload.sh