Skip to content
Stand with Ukraine flag

Installing ThingsBoard CE using Docker (Windows)

This guide covers a single-node ThingsBoard Community Edition (CE) installation using Docker Compose on Windows. By the end, you will have a fully functional ThingsBoard instance running on your machine. For cluster setup, see Cluster Setup with Docker Compose.

Ensure your server meets the minimum requirements:

Use caseCPURAMRecommended services
Development / PoC1 core4 GBThingsBoard, PostgreSQL
Production (small)2 cores8 GBThingsBoard, PostgreSQL, Kafka
Production (recommended)4+ cores16+ GBThingsBoard, PostgreSQL, Kafka, Cassandra

Install Docker: Docker Desktop for Windows

Create a dedicated directory for your ThingsBoard installation and navigate to it. All subsequent commands in this guide should be run from this directory.

Terminal window
mkdir C:\thingsboard
cd C:\thingsboard

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.

Create the docker-compose.yml file:

Terminal window
notepad docker-compose.yml

Paste one of the configurations below, save, and exit. Or use the download button to save the file directly.

services:
postgres:
restart: always
image: "postgres:18"
ports:
- "5432"
environment:
POSTGRES_DB: thingsboard
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d thingsboard"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
thingsboard-ce:
restart: always
image: "thingsboard/tb-node:4.3.1.4"

Services started:

  • postgres — PostgreSQL database
  • thingsboard-ce — ThingsBoard application node
Ports (host:container)
Port mappingDescription
8080:8080Web UI and REST API. The left value is the host port — change it if 8080 is already in use.
1883:1883MQTT — plaintext IoT device connections
8883:8883MQTT over TLS — encrypted IoT device connections
5683:5683/udpCoAP — plaintext IoT protocol
5684:5684/udpCoAP over DTLS — encrypted CoAP
5685:5685/udpLwM2M CoAP — plaintext Lightweight M2M
5686:5686/udpLwM2M CoAP over DTLS — encrypted LwM2M
5687:5687/udpLwM2M — plaintext Lightweight M2M (Bootstrap)
5688:5688/udpLwM2M over DTLS — encrypted Lightweight M2M (Bootstrap)
7070:7070Edge RPC (gRPC) — connections from ThingsBoard Edge nodes
Environment variables
VariableDescription
POSTGRES_PASSWORDPassword for the PostgreSQL postgres user. Must match SPRING_DATASOURCE_PASSWORD. Change the default value in production.
SPRING_DATASOURCE_URLPostgreSQL JDBC connection URL. Specifies the host and database name. Default: jdbc:postgresql://postgres:5432/thingsboard.
SPRING_DATASOURCE_USERNAMEPostgreSQL username ThingsBoard connects as. Default: postgres.
SPRING_DATASOURCE_PASSWORDPostgreSQL password ThingsBoard uses to connect. Must match POSTGRES_PASSWORD.
TB_QUEUE_TYPEMessage queue type. Options: in-memory (default, single-node only), kafka, rabbitmq.
TB_KAFKA_SERVERSKafka bootstrap servers. Required when TB_QUEUE_TYPE=kafka. Default: localhost:9092.
Volumes
VolumeDescription
tb-postgres-dataPersists PostgreSQL data across container restarts and upgrades.
tb-ce-kafka-dataPersists Kafka data. Only present when TB_QUEUE_TYPE=kafka.

For the full list of configuration parameters, see the Configuration Reference.

Step 2. Initialize database schema and system assets

Section titled “Step 2. Initialize database schema and system assets”

Before starting ThingsBoard, initialize the database schema and load built-in assets. Choose the option that matches your goal:

  • With demo data — also loads a sample tenant account, pre-built dashboards, and demo devices. Useful for exploring the platform before deploying to production.
  • Clean install — initializes the database with system data only (rule chains, widget bundles, system dashboards).
Terminal window
docker compose run --rm -e INSTALL_TB=true -e LOAD_DEMO=true thingsboard-ce

The container exits automatically once initialization is complete.

Start all containers:

Terminal window
docker compose up -d

Monitor the startup. The line confirming the platform is ready will be highlighted:

Terminal window
docker compose logs -f thingsboard-ce

Press Ctrl+C to detach from the log stream — containers will continue running in the background.

Open http://localhost:8080 in your browser. You should see the ThingsBoard login page. Use the following default credentials:

RoleEmailPasswordWith demo dataClean install
System Administratorsysadmin@thingsboard.orgsysadmin
Tenant Administratortenant@thingsboard.orgtenant
Customer Usercustomer@thingsboard.orgcustomer

See Getting Started for your next steps after login.

Stream the ThingsBoard container logs:

Terminal window
docker compose logs -f thingsboard-ce

Stop all containers:

Terminal window
docker compose down

Start all containers:

Terminal window
docker compose up -d

When a new ThingsBoard release becomes available, update your installation to benefit from the latest features and security patches.

See the Upgrade Instructions for detailed steps.

If you observe errors related to DNS issues, for example:

Terminal window
127.0.1.1:53: cannot unmarshal DNS message

Configure your system to use Google public DNS servers.

Connecting to PostgreSQL on the Docker host

Section titled “Connecting to PostgreSQL on the Docker host”

Inside a container, localhost and 127.0.0.1 point to the container itself, not to the Docker host. A ThingsBoard container reaches a PostgreSQL instance installed on the host through a different address.

Set the database address

The value of SPRING_DATASOURCE_URL depends on where PostgreSQL runs:

PostgreSQL locationSPRING_DATASOURCE_URL
Service in the same compose filejdbc:postgresql://postgres:5432/thingsboard
Docker hostjdbc:postgresql://host.docker.internal:5432/thingsboard
Another serverjdbc:postgresql://SERVER_IP:5432/thingsboard

Docker Desktop resolves host.docker.internal to the host automatically, so no extra compose configuration is required.

Allow the Docker subnet in PostgreSQL

A PostgreSQL instance running on the host accepts local connections only until you configure it otherwise. Find the subnet of your Docker network first:

Terminal window
docker network ls
docker network inspect NETWORK_NAME --format '{{(index .IPAM.Config 0).Subnet}}'

Set the listen address in postgresql.conf:

listen_addresses = '*'

Add a matching client entry to pg_hba.conf. The database and user must match SPRING_DATASOURCE_URL and SPRING_DATASOURCE_USERNAME, and the subnet must be the one you found. The authentication method must match how the password is stored, so use md5 instead of scram-sha-256 on instances that still store MD5 passwords:

host thingsboard DB_USER 172.18.0.0/16 scram-sha-256

Restart PostgreSQL. A reload is enough for pg_hba.conf, but listen_addresses is applied at server start only:

Terminal window
sudo systemctl restart postgresql

Verify the connection

Run psql from a temporary container. It takes the same network path as ThingsBoard, which separates a networking problem from a ThingsBoard configuration problem. Replace DB_USER and DB_PASSWORD with the values from SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD:

Terminal window
docker run --rm --add-host=host.docker.internal:host-gateway postgres:18 \
psql "postgresql://DB_USER:DB_PASSWORD@host.docker.internal:5432/thingsboard" -c "SELECT 1;"

If this command succeeds and ThingsBoard still fails, the network path is fine and the problem is in the ThingsBoard configuration.