准备
linux服务器:首先准备linux服务器,买的阿里云套餐99元/年,配置:2核2G。有个Linux服务器随便折腾。
整体部署思路
由于需要在本地修改代码然后部署,推荐采用 “本地开发 + Docker镜像构建 + 服务器部署” 的流程
操作步骤
- 启动thingsboard镜像,并查询日志,查看镜像版本。
- 把编译完成的boot.jar 上传到linux服务器,并cp到thingsboard容器里面。
- 完成自定义代码部署到Linux服务器,通过docker部署。
详细指导
部署docker
添加 Docker 软件源
ounter(lineounter(lineounter(line# 添加 Docker CE 仓库sudo wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.cloud.aliyuncs.com/docker-ce/linux/centos/docker-ce.reposudo sed -i 's|https://mirrors.aliyun.com|http://mirrors.cloud.aliyuncs.com|g' /etc/yum.repos.d/docker-ce.repo
安装兼容插件和 Docker
ounter(lineounter(lineounter(lineounter(lineounter(line# 安装 dnf 源兼容插件(Alibaba Cloud Linux 3 专用)sudo dnf -y install dnf-plugin-releasever-adapter --repo alinux3-plus# 安装 Docker 及相关组件sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动 Docker 并设置开机自启
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 启动 Docker 服务sudo systemctl start docker# 设置开机自启sudo systemctl enable docker# 验证安装docker --version
配置镜像加速器(重要)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 创建配置目录(如果不存在)sudo mkdir -p /etc/docker# 配置镜像加速器sudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.nju.edu.cn", "https://mirror.ccs.tencentyun.com" ]}EOF# 重启 Docker 使配置生效sudo systemctl daemon-reloadsudo systemctl restart docker# 确认配置生效docker info | grep -A 5 "Registry Mirrors"
防火墙配置
ounter(lineounter(line# 查看防火墙状态sudo firewall-cmd --state
如果防火墙是开启状态(running),需要开放 ThingsBoard 需要的端口:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 开放 ThingsBoard 需要的端口sudo firewall-cmd --permanent --add-port=8080/tcp # Web界面sudo firewall-cmd --permanent --add-port=1883/tcp # MQTTsudo firewall-cmd --permanent --add-port=7070/tcp # HTTP APIsudo firewall-cmd --permanent --add-port=5683-5688/udp # CoAP# 重新加载防火墙规则sudo firewall-cmd --reload# 验证规则已添加sudo firewall-cmd --list-ports
⚠️ 重要提醒:如果你的防火墙处于关闭状态(not running),可以跳过上述步骤。但无论防火墙状态如何,都必须去阿里云控制台配置安全组开放对应端口,这是云服务器的第一道防线
部署 PostgreSQL(轻量版)
2GB 内存的服务器必须使用独立数据库并限制内存
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 创建数据目录mkdir -p ~/thingsboard/postgres-data# 启动 PostgreSQL 容器(限制 512MB 内存)docker run -d \ --name postgres-tb \ --restart=unless-stopped \ --memory=512m \ --memory-swap=512m \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=thingsboard \ -p 5432:5432 \ -v ~/thingsboard/postgres-data:/var/lib/postgresql/data \ postgres:13-alpine# 确认 PostgreSQL 启动成功docker logs postgres-tb# 重启[root@iZ2zecdujvo7d47zy191u4Z ~]# docker restart postgres-tbpostgres-tb# 修改密钥[root@iZ2zecdujvo7d47zy191u4Z ~]# docker exec -it postgres-tb /bin/bash6b527c7ad78a:/# psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'postgres';"ALTER ROLE6b527c7ad78a:/# exitexit
💡 密码说明:上面的密码 postgres 是示例,建议换成自己的强密码并记好。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 1. 进入 PostgreSQL 容器docker exec -it postgres-tb /bin/bash# 2. 在容器内修改密码psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'tb_password_123';"# 3. 退出容器exit# 4. 重启 PostgreSQL 容器docker restart postgres-tb
部署 ThingsBoard
创建数据目录
ounter(lineounter(lineounter(lineounter(lineounter(linemkdir -p ~/thingsboard/data ~/thingsboard/logs# 设置正确权限(ThingsBoard 容器内使用 uid 799 运行)sudo chown -R 799:799 ~/thingsboard/datasudo chown -R 799:799 ~/thingsboard/logs
获取宿主机内网 IP
ounter(lineounter(line# 查看内网 IP(通常是 eth0 或 eth1 网卡的地址)ip addr show | grep inet | grep -v 127.0.0.1
记下内网 IP(类似 172.31.x.x 或 192.168.x.x),后面配置会用到。 案例
ounter(line[root@iZ2zecdujvo7d47zy191u4Z ~]# ip addr show | grep inet | grep -v 127.0.0.1 inet6 ::1/128 scope host inet 172.17.144.61/20 brd 172.17.159.255 scope global dynamic noprefixroute eth0 inet6 fe80::216:3eff:fe59:948f/64 scope link inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
根据你提供的输出,内网IP是 172.17.144.61(对应 eth0 网卡)。
以下是详细说明:
172.17.144.61/20:这是一个 A类私有地址(实际属于RFC 1918定义的B类地址段 172.16.0.0/12),通常用于云服务器(如阿里云)的内网通信。
172.18.0.1/16:这是 Docker 容器虚拟网桥docker0 的IP,属于虚拟内网地址,用于宿主机与容器之间的通信,不算作服务器的“主内网IP”。
inet6 ::1 和 fe80:::分别是IPv6的本地回环地址和链路本地地址,不属于传统意义上的内网IPv4地址
启动 ThingsBoard 容器(内存限制版)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 启动docker run -d \ --name thingsboard \ --restart=unless-stopped \ --memory=768m \ --memory-swap=768m \ -p 8080:8080 \ -p 1883:1883 \ -p 7070:7070 \ -p 5683-5688:5683-5688/udp \ -e SPRING_DATASOURCE_URL=jdbc:postgresql://<内网IP>:5432/thingsboard \ -e SPRING_DATASOURCE_USERNAME=postgres \ -e SPRING_DATASOURCE_PASSWORD=postgres \ -e TB_QUEUE_TYPE=in-memory \ -e TB_GATEWAY_DASHBOARD_SYNC_ENABLED=false \ -e HTTP_BIND_PORT=8080 \ -e HTTP_BIND_ADDRESS=0.0.0.0 \ -v ~/thingsboard/data:/data \ -v ~/thingsboard/logs:/var/log/thingsboard \ thingsboard/tb-postgres:latest# 启动docker run -d \ --name thingsboard \ --restart=unless-stopped \ --memory=768m \ --memory-swap=768m \ -p 8080:8080 \ -p 1883:1883 \ -p 7070:7070 \ -p 5683-5688:5683-5688/udp \ -e SPRING_DATASOURCE_URL=jdbc:postgresql://172.17.144.61:5432/thingsboard \ -e SPRING_DATASOURCE_USERNAME=postgres \ -e SPRING_DATASOURCE_PASSWORD=postgres \ -e TB_QUEUE_TYPE=in-memory \ -e TB_GATEWAY_DASHBOARD_SYNC_ENABLED=false \ -e HTTP_BIND_PORT=8080 \ -e HTTP_BIND_ADDRESS=0.0.0.0 \ -v ~/thingsboard/data:/data \ -v ~/thingsboard/logs:/var/log/thingsboard \ thingsboard/tb-postgres:latest# 停止docker stop thingsboard# 重启docker restart thingsboard# 删除镜像docker rm thingsboard
重点配置说明: TB_GATEWAY_DASHBOARD_SYNC_ENABLED=false 关闭github同步前端插件。
公网访问,不配置公网访问不了。 -e HTTP_BIND_PORT=8080 -e HTTP_BIND_ADDRESS=0.0.0.0 \
查看启动日志
实时打印:
ounter(lineounter(line# 查看日志,等待启动完成(可能需要 3-5 分钟)docker logs -f thingsboard
看到类似 Started Thingsboard in XXX seconds 的日志就说明成功了。
ounter(line2026-03-29 05:45:31,548 [main] INFO o.t.s.ThingsboardServerApplication - Started ThingsBoard in 51 seconds
确认 Docker 容器是否正常运行
ounter(lineounter(lineounter(lineounter(lineounter(line# 查看容器状态docker ps -a | grep thingsboard# 查看容器日志,确认是否启动成功docker logs --tail 50 thingsboard
预期输出:
日志最后应该显示 Started ThingsboardServer in XXX seconds
如果容器状态是 Exited,说明容器启动失败,需要查看错误日志。
检查容器端口是否正常监听
ounter(lineounter(lineounter(lineounter(lineounter(line# 查看 8080 端口是否在监听状态netstat -tlnp | grep 8080# 或者用 ss 命令ss -tlnp | grep 8080
预期输出:
ounter(linetcp6 0 0 :::8080 :::* LISTEN 12345/docker-proxy
在服务器本地测试(绕过网络问题) 这一步可以确认服务本身是否正常,而不是被外部网络拦截:
ounter(lineounter(line# 在服务器上用 curl 测试本地的 8080 端口curl -I http://localhost:8080
查看容器状态和日志
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 1. 查看容器运行状态docker ps -a | grep thingsboard# 2. 查看完整的容器日志(重点关注错误)docker logs thingsboard 2>&1 | tail -100# 3. 查看容器内进程docker exec thingsboard ps aux
执行以下命令查看详细错误
ounter(lineounter(lineounter(lineounter(lineounter(line# 查看 ThingsBoard 容器的完整日志(重点关注错误和异常)docker logs thingsboard 2>&1 | grep -E "ERROR|Exception|Caused by|Failed|Unable" | tail -50# 如果没有错误信息,查看最后 100 行完整日志docker logs thingsboard --tail 100
查看启动日志确认启动的版本
ounter(lineounter(lineounter(lineounter(linedocker logs thingsboard 2>&1 | grep -E "version" | tail -50# 结果2026-03-29 05:45:17,782 [main] INFO o.t.s.c.SystemInfoController - System build info: {"version":"4.2.1.1","artifact":"application","name":"ThingsBoard Server Application","type":"CE"}
确认版本:4.2.1.1
安全组配置(关键!)
6.1 操作步骤
添加以下规则: ![[Pasted image 20260329132223.png]]
访问验证
浏览器打开:http://你的服务器公网IP:8080
默认账号:
邮箱:tenant@thingsboard.org
部署本地修改的 ThingsBoard
方式一:直接替换容器内的文件
ounter(lineounter(lineounter(lineounter(lineounter(line# 把修改过的 jar 包复制到容器中docker cp /本地路径/your-modified.jar thingsboard:/usr/share/thingsboard/bin/thingsboard.jar# 重启容器docker restart thingsboard
ounter(linedocker cp ./thingsboard-4.3.0.1-boot.jar thingsboard:/usr/share/thingsboard/bin/thingsboard.jar
方式二:构建自定义镜像
在本地创建 Dockerfile:
ounter(lineounter(lineFROM thingsboard/tb-postgres:latestCOPY ./your-modified-thingsboard.jar /usr/share/thingsboard/bin/thingsboard.jar
本地构建并推送:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 构建镜像docker build -t my-thingsboard:latest .# 导出镜像docker save my-thingsboard:latest -o my-thingsboard.tar# 上传到服务器scp my-thingsboard.tar root@你的服务器IP:/root/# 在服务器上导入docker load -i /root/my-thingsboard.tar# 用新镜像启动(先停止并删除旧容器)docker stop thingsboard && docker rm thingsboarddocker run -d \ --name thingsboard \ ...(其他参数同上)... my-thingsboard:latest
常用管理命令速查
| |
|---|
| docker ps -a |
| docker stats |
| docker logs -f thingsboard |
| docker restart thingsboard |
| docker stop thingsboard |
| docker exec -it thingsboard /bin/bash |
| sudo firewall-cmd --list-all |
| docker images |
注意事项
内存限制是关键:2GB 内存跑 ThingsBoard 属于极限配置,数据库和主容器都必须限制内存。如果容器频繁被 kill,适当降低内存限制。
不要用 Cassandra:官方文档推荐 PostgreSQL 而非 Cassandra,后者内存占用更高。
开发/演示用途:这套配置只适合开发测试,生产环境建议升级到 4GB 以上内存。
防火墙两层检查:服务无法访问时,按顺序检查:安全组 → 系统防火墙(firewalld) → 容器是否运行。