Installing ThingsBoard on CentOS/RHEL
This guide covers installing ThingsBoard on CentOS/RHEL Server, from a clean environment to a fully running instance. By the end, you will have a licensed, activated ThingsBoard instance — free, no credit card required — with a system administrator account and, optionally, a demo tenant.
Prerequisites
Section titled “Prerequisites”- RHEL 9, CentOS Stream 9, or derivatives (AlmaLinux, Rocky Linux, Oracle Linux, etc.). ThingsBoard requires Java 25, and the
java-25-openjdkpackages ship with RHEL 9.7 and newer. - A user account with
sudoprivileges - Outbound internet access to download packages and to reach the ThingsBoard License Portal during activation
Ensure your server meets the minimum requirements:
| Use case | CPU | RAM | Storage | Recommended services |
|---|---|---|---|---|
| Development / PoC | 1 core | 4 GB | 20 GB | ThingsBoard, PostgreSQL |
| Production (small) | 2 cores | 8 GB | 100 GB SSD | ThingsBoard, PostgreSQL, Kafka |
| Production (recommended) | 4+ cores | 16+ GB | 200+ GB SSD | ThingsBoard, PostgreSQL, Kafka, Cassandra |
Install required tools:
sudo dnf install -y wgetsudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpmStep 1. Install Java (OpenJDK)
Section titled “Step 1. Install Java (OpenJDK)”ThingsBoard runs on the Java Virtual Machine and requires Java 25. Install OpenJDK 25:
sudo dnf install -y java-25-openjdk-headlessSet OpenJDK 25 as the default Java version. Use the non-interactive command:
sudo update-alternatives --set java /usr/lib/jvm/java-25-openjdk/bin/javaIf you have multiple Java versions installed and prefer to choose interactively:
sudo update-alternatives --config javaVerify the installation:
java -versionThe reported version must be 25.
Step 2. Install ThingsBoard Package
Section titled “Step 2. Install ThingsBoard Package”Install the font libraries required by the built-in reporting component:
sudo dnf install -y harfbuzz fontconfig dejavu-sans-fontsDownload and install the ThingsBoard 4.4.0 package:
wget https://github.com/thingsboard/thingsboard/releases/download/v4.4/thingsboard-4.4.rpmsudo rpm -Uvh thingsboard-4.4.rpmVerify the installation:
rpm -qa | grep thingsboardThe installed package is listed in the output.
Step 3. Configure Database
Section titled “Step 3. Configure Database”ThingsBoard stores two kinds of data: entities (devices, assets, dashboards, users) and time-series telemetry. Choose the database configuration that matches your expected load:
- PostgreSQL only — stores all data (entities and time-series) in PostgreSQL. Recommended for most deployments handling up to 5,000 messages per second. Simple to operate with minimal infrastructure requirements.
- Hybrid (PostgreSQL + Cassandra) — stores entities in PostgreSQL and time-series data in Cassandra. Designed for high-throughput deployments exceeding 5,000 messages per second or with millions of devices. Requires significant additional resources: at least 8 GB RAM, a dedicated multi-core CPU, and fast SSD storage for the Cassandra node.
Install the PostgreSQL repository:
sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpmInstall and start PostgreSQL 18:
sudo dnf -qy module disable postgresqlsudo dnf -y install postgresql18 postgresql18-server postgresql18-contribsudo /usr/pgsql-18/bin/postgresql-18-setup initdbsudo systemctl enable --now postgresql-18Export your PostgreSQL password as an environment variable — this value will be used in the following steps:
TB_DB_PASSWORD=YOUR_PASSWORDSet the password for the postgres user and create the ThingsBoard database:
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$TB_DB_PASSWORD';"sudo -u postgres psql -c "CREATE DATABASE thingsboard;"Add the database configuration to the ThingsBoard configuration file:
sudo tee -a /etc/thingsboard/conf/thingsboard.conf > /dev/null << EOF# DB Configurationexport DATABASE_TS_TYPE=sqlexport SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboardexport SPRING_DATASOURCE_USERNAME=postgresexport SPRING_DATASOURCE_PASSWORD=$TB_DB_PASSWORDEOFInstall the PostgreSQL repository:
sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpmInstall and start PostgreSQL 18:
sudo dnf -qy module disable postgresqlsudo dnf -y install postgresql18 postgresql18-server postgresql18-contribsudo /usr/pgsql-18/bin/postgresql-18-setup initdbsudo systemctl enable --now postgresql-18Export your PostgreSQL password as an environment variable — this value will be used in the following steps:
TB_DB_PASSWORD=YOUR_PASSWORDSet the password for the postgres user and create the ThingsBoard database:
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$TB_DB_PASSWORD';"sudo -u postgres psql -c "CREATE DATABASE thingsboard;"Install Cassandra:
sudo rpm --import https://downloads.apache.org/cassandra/KEYSsudo tee /etc/yum.repos.d/cassandra.repo > /dev/null <<'EOF'[cassandra]name=Apache Cassandrabaseurl=https://redhat.cassandra.apache.org/50x/gpgcheck=1repo_gpgcheck=0gpgkey=https://downloads.apache.org/cassandra/KEYSEOFsudo dnf -y update && sudo dnf -y install cassandra cassandra-tools chkconfigsudo systemctl daemon-reexecsudo systemctl start cassandra.servicesudo chkconfig cassandra onVerify Cassandra is running:
nodetool statusThe status column should show UN (Up/Normal). Wait a few moments for Cassandra to initialize if needed.
Add the database configuration to the ThingsBoard configuration file:
sudo tee -a /etc/thingsboard/conf/thingsboard.conf > /dev/null << EOF# DB Configurationexport DATABASE_TS_TYPE=cassandraexport SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboardexport SPRING_DATASOURCE_USERNAME=postgresexport SPRING_DATASOURCE_PASSWORD=$TB_DB_PASSWORDEOFIf you are using an external Cassandra cluster, also add the following to /etc/thingsboard/conf/thingsboard.conf:
export CASSANDRA_CLUSTER_NAME="Thingsboard Cluster"export CASSANDRA_KEYSPACE_NAME=thingsboardexport CASSANDRA_URL=127.0.0.1:9042export CASSANDRA_USE_CREDENTIALS=falseexport CASSANDRA_USERNAME=export CASSANDRA_PASSWORD=Step 4. Choose Queue Service
Section titled “Step 4. Choose Queue Service”ThingsBoard uses a message queue to route messages between its internal services. Select the option that matches your infrastructure:
- In Memory (default) — built-in queue, no extra setup required. Suitable for development and PoC. Not recommended for production or multi-node deployments.
- Kafka — high-throughput, durable queue. Run it yourself or use a managed service such as AWS MSK.
- Confluent Cloud — fully managed Kafka service. Use this if you want Kafka without managing the infrastructure yourself.
In Memory queue is built-in and enabled by default. No configuration needed.
This example runs Kafka as a Docker container on the same host. If you already have a Kafka broker or use a managed service (e.g. AWS MSK), skip the Docker setup and point TB_KAFKA_SERVERS at your broker instead.
Install Docker: see Docker for CentOS/RHEL.
Create a directory for your Docker Compose files and add the Kafka configuration:
mkdir -p ~/thingsboardsudo tee ~/thingsboard/docker-compose-kafka.yml > /dev/null << 'EOF'services: kafka: restart: always image: bitnamilegacy/kafka:4.0 ports: - 9092:9092 - 9093 - 9094 environment: ALLOW_PLAINTEXT_LISTENER: "yes" KAFKA_CFG_LISTENERS: "OUTSIDE://:9092,CONTROLLER://:9093,INSIDE://:9094" KAFKA_CFG_ADVERTISED_LISTENERS: "OUTSIDE://localhost:9092,INSIDE://kafka:9094" KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT,CONTROLLER:PLAINTEXT" KAFKA_CFG_INTER_BROKER_LISTENER_NAME: "INSIDE" KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "false" KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1" KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1" KAFKA_CFG_PROCESS_ROLES: "controller,broker" KAFKA_CFG_NODE_ID: "0" KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "0@kafka:9093" volumes: - kafka-data:/bitnamivolumes: kafka-data: driver: localEOFStart Kafka:
docker compose -f ~/thingsboard/docker-compose-kafka.yml up -dAdd the following configuration to /etc/thingsboard/conf/thingsboard.conf:
sudo tee -a /etc/thingsboard/conf/thingsboard.conf > /dev/null << 'EOF'export TB_QUEUE_TYPE=kafkaexport TB_KAFKA_SERVERS=localhost:9092EOFCreate a Confluent Cloud account, create a Kafka cluster, and obtain your API Key. Add the following lines to /etc/thingsboard/conf/thingsboard.conf, replacing CLUSTER_API_KEY, CLUSTER_API_SECRET, and localhost:9092 with your Confluent Cloud values:
sudo tee -a /etc/thingsboard/conf/thingsboard.conf > /dev/null << 'EOF'export TB_QUEUE_TYPE=kafkaexport TB_QUEUE_KAFKA_USE_CONFLUENT_CLOUD=trueexport TB_KAFKA_SERVERS=localhost:9092export TB_QUEUE_KAFKA_REPLICATION_FACTOR=3export TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG='org.apache.kafka.common.security.plain.PlainLoginModule required username="CLUSTER_API_KEY" password="CLUSTER_API_SECRET";'export TB_QUEUE_CORE_POLL_INTERVAL_MS=1000export TB_QUEUE_CORE_PARTITIONS=2export TB_QUEUE_RULE_ENGINE_POLL_INTERVAL_MS=1000export TB_QUEUE_TRANSPORT_REQUEST_POLL_INTERVAL_MS=1000export TB_QUEUE_TRANSPORT_RESPONSE_POLL_INTERVAL_MS=1000export TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS=1000export TB_QUEUE_VC_INTERVAL_MS=1000export TB_QUEUE_VC_PARTITIONS=1EOFYou can adjust the default Rule Engine queue configuration later from the UI. See Rule Engine Queues for details.
Step 5. [Optional] Memory Configuration
Section titled “Step 5. [Optional] Memory Configuration”By default, ThingsBoard sets no explicit memory limit — the JVM can consume all available RAM, which may cause the OS to kill the process under memory pressure. On smaller machines, set the maximum heap size explicitly. The values below are approximate and suited for a single-node setup with In Memory queue and PostgreSQL database:
sudo tee -a /etc/thingsboard/conf/thingsboard.conf > /dev/null << 'EOF'# Maximum heap size — set to half of available RAM.# Example: 2G for a 4 GB server, 4G for an 8 GB server, 8G for a 16 GB server.export JAVA_OPTS="$JAVA_OPTS -Xms4G -Xmx4G -Xss512k -XX:+AlwaysPreTouch"EOFWe recommend adjusting these parameters depending on your server resources. Set it to at least 2G (gigabytes), and increase it if there is additional RAM available. Use half of your total RAM if you do not run any other memory-intensive processes (e.g. Cassandra), or one third otherwise.
Step 6. Run Installation Script
Section titled “Step 6. Run Installation Script”Run the installation script to initialize the database schema:
sudo /usr/share/thingsboard/bin/install/install.shStep 7. Start ThingsBoard
Section titled “Step 7. Start ThingsBoard”Start the ThingsBoard service:
sudo systemctl start thingsboardMonitor the startup. The line confirming the platform is ready will be highlighted:
tail -f /var/log/thingsboard/thingsboard.log | grep --line-buffered --color=always -E 'Started ThingsboardServerApplication|$'Configure Firewall
Section titled “Configure Firewall”Open the required ports in your firewall so devices and users can reach the platform — expand the list below for the full set of ports and protocols.
Full port list
| Port | Protocol | Description |
|---|---|---|
8080 | TCP | Web UI and REST API. Not required if using a load balancer. |
1883 | TCP | MQTT |
8883 | TCP | MQTT over SSL |
5683 | UDP | CoAP |
5684 | UDP | CoAP over DTLS |
5685 | UDP | LwM2M CoAP |
5686 | UDP | LwM2M CoAP over DTLS |
5687 | UDP | LwM2M (Bootstrap) |
5688 | UDP | LwM2M over DTLS (Bootstrap) |
161 | UDP | SNMP |
7070 | TCP | Edge RPC (gRPC) |
9090 | TCP | Remote Integration Executor (gRPC) |
Access ThingsBoard Web UI
Section titled “Access ThingsBoard Web UI”Open ThingsBoard in a web browser:
http://localhost:8080On first launch you are greeted with the activation screen:
Welcome to ThingsBoard 4.4.0Get your free license and start buildingContinue with the next step to license and activate your instance.
Step 8. License and Activate Your Instance
Section titled “Step 8. License and Activate Your Instance”Opening ThingsBoard in your browser for the first time shows an activation welcome screen.
- Click Open the License Portal, then create an account or sign in.
- Choose a free license: Commercial (up to 100 devices, one server) or Non-commercial (up to 1,000 devices, any number of servers).
- Check the confirmation box to agree to the Terms of Use, Privacy Policy, and ThingsBoard License (BUSL 1.1), then click Accept and activate to issue the license and activate your instance.
- Click Continue setup on your instance to proceed to account creation. Your license key stays available on this screen and in your License Portal account.
- Click Already have a license?, paste your license key, and click Activate.
- Your instance is now activated. The license is saved on this server and in your License Portal account.
Step 9. Create Your Administrator Account
Section titled “Step 9. Create Your Administrator Account”Once activated, ThingsBoard prompts you to create your System Administrator account — the account that manages the platform itself (tenants, system settings, platform-wide resources).
- Enter Email, Password, and Confirm password.
- 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.
- Click Create account. You are signed in as the system administrator.
Your ThingsBoard instance is now installed and running.
[Optional] Install ThingsBoard WebReport Component
Section titled “[Optional] Install ThingsBoard WebReport Component”The WebReport service renders dashboards into PDF and PNG reports. Install it if you need scheduled or on-demand dashboard reports. Choose one of the installation methods below:
Install Docker: see Docker for CentOS/RHEL.
Create the Docker Compose file ~/thingsboard/tb-web-report.yml:
mkdir -p ~/thingsboardsudo tee ~/thingsboard/tb-web-report.yml > /dev/null << 'EOF'services: tb-web-report: container_name: tb-web-report restart: always image: "thingsboard/tb-web-report:4.4.0" ports: - "8383:8383" environment: HTTP_BIND_ADDRESS: "0.0.0.0" HTTP_BIND_PORT: "8383" LOGGER_LEVEL: "info" LOG_FOLDER: "logs" LOGGER_FILENAME: "tb-web-report-%DATE%.log" DOCKER_MODE: "true" DEFAULT_PAGE_NAVIGATION_TIMEOUT: "120000" DASHBOARD_IDLE_WAIT_TIME: "3000" USE_NEW_PAGE_FOR_REPORT: "true"EOFStart the WebReport service:
docker compose -f ~/thingsboard/tb-web-report.yml up -dCheck the container logs:
docker logs -f tb-web-reportDownload the WebReport installation package:
wget https://github.com/thingsboard/thingsboard/releases/download/v4.4/tb-web-report-4.4.rpmInstall the required libraries:
sudo dnf install -y pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc unzip nssInstall the Roboto fonts:
sudo dnf install -y google-roboto-fontsInstall and start the WebReport service:
sudo rpm -Uvh tb-web-report-4.4.rpmsudo systemctl start tb-web-report[Optional] Configure HTTPS
Section titled “[Optional] Configure HTTPS”Serving ThingsBoard over HTTPS encrypts the traffic between browsers and the server and prevents browser security warnings. HTTPS is handled by HAProxy: it accepts incoming traffic on ports 80 (HTTP) and 443 (HTTPS), terminates TLS with a trusted certificate from Let’s Encrypt, and forwards requests to ThingsBoard.
Before you start, make sure that:
- a domain name is assigned to your server, and its DNS record points to the server’s IP address;
- ports 80 and 443 are reachable from the internet.
Follow Configure HAProxy on CentOS/RHEL to install HAProxy and generate the certificate.
Troubleshooting
Section titled “Troubleshooting”Check the service status:
sudo systemctl status thingsboardThingsBoard logs are stored in /var/log/thingsboard. Check for errors:
grep ERROR /var/log/thingsboard/thingsboard.logMonitor logs in real time:
tail -f /var/log/thingsboard/thingsboard.logOr follow the service log through journald:
sudo journalctl -u thingsboard.service -f --no-pagerFor more troubleshooting tips, see the Troubleshooting guide.
Next Steps
Section titled “Next Steps”With ThingsBoard running, these concept guides help you build your first solution:
- Getting Started — a guided walkthrough of the platform after installation.
- Multi-Tenancy & Hierarchy — how tenants, customers, and users are organized.
- Digital Twin Model — how devices and assets are modeled in the platform.
- Data Processing — how the Rule Engine transforms and routes incoming data.
- Alarms & Notifications — how to detect conditions and notify users.
- Data Visualization — how to build dashboards and widgets.
Was this helpful?