Skip to content
© 2026 The ThingsBoard Authors
Try for free

ThingsBoard Cloud

Choose your data region

Your data stays in the region you choose, for residency and compliance. No credit card required.

Rather run it yourself? Install on your own servers

AKS Microservices Setup

This guide walks you through deploying ThingsBoard in microservices mode on Azure Kubernetes Service (AKS). We use Azure Database for PostgreSQL as the managed database.

Install kubectl and az CLI tools.

Log in to Azure:

Terminal window
az login

Verify that you can pull the images from Docker Hub:

Terminal window
docker pull thingsboard/tb-node:4.4.0
docker pull thingsboard/tb-web-report:4.4.0
docker pull thingsboard/tb-web-ui:4.4.0
docker pull thingsboard/tb-js-executor:4.4.0
docker pull thingsboard/tb-http-transport:4.4.0
docker pull thingsboard/tb-mqtt-transport:4.4.0
docker pull thingsboard/tb-coap-transport:4.4.0
docker pull thingsboard/tb-lwm2m-transport:4.4.0
docker pull thingsboard/tb-snmp-transport:4.4.0
docker pull thingsboard/tb-integration-executor:4.4.0

Step 1. Clone ThingsBoard K8S Scripts Repository

Section titled “Step 1. Clone ThingsBoard K8S Scripts Repository”

Clone the repository containing the Kubernetes deployment scripts:

Terminal window
git clone -b release-4.4.0 https://github.com/thingsboard/thingsboard-pe-k8s.git --depth 1
cd thingsboard-pe-k8s/azure/microservices
Terminal window
export AKS_RESOURCE_GROUP=ThingsBoardResources
export AKS_LOCATION=eastus
export AKS_GATEWAY=tb-gateway
export TB_CLUSTER_NAME=tb-cluster
export TB_DATABASE_NAME=tb-db
export TB_REDIS_NAME=tb-redis
echo "Resource group: $AKS_RESOURCE_GROUP, location: $AKS_LOCATION, cluster: $TB_CLUSTER_NAME, database: $TB_DATABASE_NAME"
Variable Default Description
AKS_RESOURCE_GROUP ThingsBoardResources Azure Resource Group name
AKS_LOCATION eastus Azure region. Run az account list-locations for options
AKS_GATEWAY tb-gateway Azure Application Gateway name
TB_CLUSTER_NAME tb-cluster AKS cluster name
TB_DATABASE_NAME tb-db PostgreSQL server name
TB_REDIS_NAME tb-redis Valkey/Redis cache name

Create the Azure Resource Group:

Terminal window
az group create --name $AKS_RESOURCE_GROUP --location $AKS_LOCATION

See az group for more info.

Create the AKS cluster with 3 nodes:

Terminal window
az aks create --resource-group $AKS_RESOURCE_GROUP \
--name $TB_CLUSTER_NAME \
--generate-ssh-keys \
--enable-addons ingress-appgw \
--appgw-name $AKS_GATEWAY \
--appgw-subnet-cidr "10.2.0.0/16" \
--node-vm-size Standard_DS3_v2 \
--node-count 3

Key parameters:

  • node-count — number of nodes per pool (default: 3)
  • node-vm-size — VM size (default: Standard_DS2_v2)
  • enable-addons — enables Application Gateway as a path-based load balancer
  • generate-ssh-keys — generates SSH keys if missing (stored in ~/.ssh)

See az aks create for the full parameter list. Alternatively, follow the portal-based cluster setup guide.

Terminal window
az aks get-credentials --resource-group $AKS_RESOURCE_GROUP --name $TB_CLUSTER_NAME

Verify the connection:

Terminal window
kubectl get nodes

You need to set up PostgreSQL on Azure. ThingsBoard uses it as the main database.

You may follow the Azure portal guide, keeping these requirements in mind:

  • PostgreSQL version 16.x
  • The instance must be accessible from the AKS cluster
  • Use thingsboard as the initial database name
  • High availability enabled is recommended for production

Alternatively, create using the CLI (replace POSTGRES_USER and POSTGRES_PASS with your credentials):

Terminal window
az postgres flexible-server create --location $AKS_LOCATION --resource-group $AKS_RESOURCE_GROUP \
--name $TB_DATABASE_NAME --admin-user POSTGRES_USER --admin-password POSTGRES_PASS \
--public-access 0.0.0.0 --storage-size 32 \
--version 16 -d thingsboard

Note the host value from the command output (e.g. tb-db.postgres.database.azure.com). Also note the username and password.

Edit tb-node-db-configmap.yml and replace YOUR_AZURE_POSTGRES_ENDPOINT_URL, YOUR_AZURE_POSTGRES_USER, and YOUR_AZURE_POSTGRES_PASSWORD with the correct values:

Terminal window
nano tb-node-db-configmap.yml

Using Cassandra is optional. We recommend it if you plan to insert more than 5K data points per second or want to optimize storage space.

Create 3 separate node pools with 1 node per zone. At least 4 vCPUs and 16 GB of RAM is recommended.

Terminal window
az aks nodepool add --resource-group $AKS_RESOURCE_GROUP --cluster-name $TB_CLUSTER_NAME --name tbcassandra1 --node-count 1 --zones 1 --labels role=cassandra
az aks nodepool add --resource-group $AKS_RESOURCE_GROUP --cluster-name $TB_CLUSTER_NAME --name tbcassandra2 --node-count 1 --zones 2 --labels role=cassandra
az aks nodepool add --resource-group $AKS_RESOURCE_GROUP --cluster-name $TB_CLUSTER_NAME --name tbcassandra3 --node-count 1 --zones 3 --labels role=cassandra

Create the namespace, then deploy Cassandra:

Terminal window
kubectl apply -f tb-namespace.yml
kubectl config set-context $(kubectl config current-context) --namespace=thingsboard
kubectl apply -f receipts/cassandra.yml
Terminal window
echo " DATABASE_TS_TYPE: cassandra" >> tb-node-db-configmap.yml
echo " CASSANDRA_URL: cassandra:9042" >> tb-node-db-configmap.yml
echo " CASSANDRA_LOCAL_DATACENTER: dc1" >> tb-node-db-configmap.yml

Create the ThingsBoard keyspace inside Cassandra:

Terminal window
kubectl exec -it cassandra-0 -- bash -c "cqlsh -e \
\"CREATE KEYSPACE IF NOT EXISTS thingsboard \
WITH replication = { \
'class' : 'NetworkTopologyStrategy', \
'dc1' : '3' \
};\""

ThingsBoard uses cache to improve performance and avoid frequent DB reads. By default, the deployment already uses local Valkey cache. Azure does not provide a managed Valkey cluster. Instead of the default deployment, you can set up your own Valkey cluster according to the Azure documentation.

Edit the thirdparty.yml file, find the StatefulSet section named tb-valkey, and set the spec.replicas value to 0.

Once your Valkey cluster is ready, edit tb-cache-configmap.yml and replace REDIS_HOST with your Valkey endpoint. For cluster mode, use:

REDIS_CONNECTION_TYPE: cluster
REDIS_NODES: (Comma-separated list of "host:port" pairs)

We assume you have already chosen your subscription plan or decided to purchase a perpetual license. If not, navigate to the pricing page.

Create a docker secret with your license key:

Terminal window
export TB_LICENSE_KEY=PUT_YOUR_LICENSE_KEY_HERE
kubectl create -n thingsboard secret generic tb-license --from-literal=license-key=$TB_LICENSE_KEY

Run the initial database setup:

Terminal window
./k8s-install-tb.sh

After this command finishes you should see:

Installation finished successfully!

Deploy thirdparty components and main ThingsBoard microservices:

Terminal window
./k8s-deploy-resources.sh

After a few minutes, call kubectl get pods. If everything went fine, you should see tb-node-0 pod in the READY state.

Deploy the transport microservices you need. Omit protocols you don’t use to save resources:

Terminal window
# HTTP Transport (optional)
kubectl apply -f transports/tb-http-transport.yml
# MQTT Transport (optional)
kubectl apply -f transports/tb-mqtt-transport.yml
# CoAP Transport (optional)
kubectl apply -f transports/tb-coap-transport.yml
# LwM2M Transport (optional)
kubectl apply -f transports/tb-lwm2m-transport.yml
# SNMP Transport (optional)
kubectl apply -f transports/tb-snmp-transport.yml

You have 2 options:

  • HTTP — recommended for development. Simple configuration and minimum costs.
  • HTTPS — recommended for production. Requires an SSL certificate uploaded to Application Gateway.
Terminal window
kubectl apply -f receipts/http-load-balancer.yml

Check the status:

Terminal window
kubectl get ingress

Once provisioned, you should see output similar to:

NAME CLASS HOSTS ADDRESS PORTS AGE
tb-http-loadbalancer <none> * 34.111.24.134 80 7m25s

Use the address to access the web UI and connect devices via HTTP API.

Administrator account creation on first access is covered next, in Step 11. Create Your Administrator Account.

10.2 Configure MQTT Load Balancer (Optional)

Section titled “10.2 Configure MQTT Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/mqtt-load-balancer.yml

The load balancer forwards all TCP traffic for ports 1883 and 8883.

For MQTT over SSL, follow the MQTT over SSL guide to configure transport/tb-mqtt-transport.yml.

10.3 Configure CoAP Load Balancer (Optional)

Section titled “10.3 Configure CoAP Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/coap-load-balancer.yml

The load balancer forwards UDP traffic for ports 5683 (CoAP non-secure) and 5684 (CoAP secure DTLS).

For CoAP over DTLS, follow the CoAP over DTLS guide to configure transport/tb-coap-transport.yml.

10.4 Configure LwM2M Load Balancer (Optional)

Section titled “10.4 Configure LwM2M Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/lwm2m-load-balancer.yml

The load balancer forwards UDP traffic for ports 5685–5688.

For LwM2M over DTLS, follow the LwM2M over DTLS guide to configure transport/tb-lwm2m-transport.yml.

10.5 Configure Edge Load Balancer (Optional)

Section titled “10.5 Configure Edge Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/edge-load-balancer.yml

The load balancer forwards all TCP traffic on port 7070.

Step 11. Create Your Administrator Account

Section titled “Step 11. Create Your Administrator Account”

After launching ThingsBoard, open the web UI at the load balancer address. ThingsBoard prompts you to create your System Administrator account — the account that manages the platform itself (tenants, system settings, platform-wide resources).

  1. Enter Email, Password, and Confirm password.
  2. The Set up a demo tenant option is selected by default: it creates a ready-made tenant with dashboards, devices, and rule chains for exploring the platform before building your own solution. Clear it if you want to start with an empty platform.
  3. Click Create account. You are signed in as the system administrator.

Your ThingsBoard instance is now installed and running.

Confirm that the load balancers created in Step 10 are provisioned and reachable, and note their addresses — you need them to open the web UI and to connect devices.

Check the status of the ingress you created for the HTTP(S) load balancer:

Terminal window
kubectl get ingress

Once an external IP address is assigned, use it to open the ThingsBoard web interface in your browser.

List the cluster services to find the external IP addresses assigned to the load balancers you configured:

Terminal window
kubectl get service

Two load balancers are available:

  • tb-mqtt-loadbalancer — for TCP (MQTT) protocol
  • tb-udp-loadbalancer — for UDP (CoAP/LwM2M) protocol

Use the EXTERNAL-IP field of each load balancer to connect devices.

Pull the Trendz images from Docker Hub:

Terminal window
docker pull thingsboard/trendz:1.16.0
docker pull thingsboard/trendz-python-executor:1.16.0

Create a Trendz Database in the Existing Azure Database

Section titled “Create a Trendz Database in the Existing Azure Database”

Edit trendz/trendz-secret.yml and replace YOUR_AZURE_POSTGRES_ENDPOINT_URL, YOUR_AZURE_POSTGRES_USER, and YOUR_AZURE_POSTGRES_PASSWORD, then apply:

Terminal window
kubectl apply -f ./trendz/trendz-secret.yml
kubectl apply -f ./trendz/trendz-create-db.yml

Check logs:

Terminal window
kubectl logs job/trendz-create-db -n thingsboard
Terminal window
./k8s-deploy-trendz.sh

After this command finishes you should see:

Trendz installed successfully!

Stream the logs of the ThingsBoard node pod to diagnose startup or runtime issues:

Terminal window
kubectl logs -f tb-node-0

See the kubectl Cheat Sheet for more details.

Delete ThingsBoard pods and load balancers:

Terminal window
./k8s-delete-resources.sh

Delete all data including database:

Terminal window
./k8s-delete-all.sh

Delete the AKS cluster:

Terminal window
az aks delete --resource-group $AKS_RESOURCE_GROUP --name $TB_CLUSTER_NAME

With ThingsBoard running, these concept guides help you build your first solution: