thingsboard/summary/16-docker-install-tb.sh脚本详解.md

477 lines
13 KiB
Markdown
Raw Permalink Normal View History

2026-01-19 11:50:37 +08:00
# docker-install-tb.sh 脚本详解
## 1. 脚本概述
`docker-install-tb.sh` 是 ThingsBoard **数据库初始化和安装脚本**,用于首次部署时创建数据库 schema 和可选的演示数据。
## 2. 脚本功能
这个脚本主要做两件事:
1. **启动依赖服务**启动数据库和缓存服务PostgreSQL/Cassandra、Valkey
2. **执行数据库初始化**:运行 `tb-core1` 容器执行数据库 schema 创建
## 3. 详细执行流程
### 3.1 步骤1解析命令行参数
```bash
# 第18-32行解析 --loadDemo 参数
while [[ $# -gt 0 ]]
do
case $key in
--loadDemo)
LOAD_DEMO=true
shift
;;
esac
done
# 第34-38行设置 loadDemo 变量
if [ "$LOAD_DEMO" == "true" ]; then
loadDemo=true
else
loadDemo=false
fi
```
**作用**
- 解析 `--loadDemo` 参数
- 如果提供 `--loadDemo`,则设置 `loadDemo=true`,后续会加载演示数据
- 如果不提供,则 `loadDemo=false`,只创建数据库 schema
**使用示例**
```bash
./docker-install-tb.sh # 不加载演示数据
./docker-install-tb.sh --loadDemo # 加载演示数据
```
### 3.2 步骤2加载工具函数
```bash
# 第42行加载 compose-utils.sh
source compose-utils.sh
```
**作用**
- 加载 `compose-utils.sh` 中的所有工具函数
- 这些函数用于根据 `.env` 配置选择对应的 Compose 文件
### 3.3 步骤3检测 Docker Compose 版本
```bash
# 第44行检测 Docker Compose 版本V1 或 V2
COMPOSE_VERSION=$(composeVersion) || exit $?
```
**作用**
- 检测系统中安装的是 Docker Compose V1 (`docker-compose`) 还是 V2 (`docker compose`)
- 后续会根据版本使用不同的命令
### 3.4 步骤4选择配置组合
```bash
# 第46-54行根据 .env 配置选择对应的 Compose 文件
ADDITIONAL_COMPOSE_QUEUE_ARGS=$(additionalComposeQueueArgs) || exit $?
ADDITIONAL_COMPOSE_ARGS=$(additionalComposeArgs) || exit $?
ADDITIONAL_CACHE_ARGS=$(additionalComposeCacheArgs) || exit $?
ADDITIONAL_COMPOSE_EDQS_ARGS=$(additionalComposeEdqsArgs) || exit $?
ADDITIONAL_STARTUP_SERVICES=$(additionalStartupServices) || exit $?
```
**作用**
- `additionalComposeQueueArgs()`: 根据 `TB_QUEUE_TYPE` 选择队列配置kafka/confluent
- `additionalComposeArgs()`: 根据 `DATABASE` 选择数据库配置postgres/hybrid
- `additionalComposeCacheArgs()`: 根据 `CACHE` 选择缓存配置valkey/valkey-cluster/valkey-sentinel
- `additionalComposeEdqsArgs()`: 根据 `EDQS_ENABLED` 选择 EDQS 配置
- `additionalStartupServices()`: 返回需要先启动的服务列表(数据库和缓存)
**返回示例**(假设 `.env``DATABASE=postgres`, `CACHE=valkey`, `TB_QUEUE_TYPE=kafka`
```bash
ADDITIONAL_COMPOSE_ARGS="-f docker-compose.postgres.yml"
ADDITIONAL_CACHE_ARGS="-f docker-compose.valkey.yml"
ADDITIONAL_COMPOSE_QUEUE_ARGS="-f docker-compose.kafka.yml"
ADDITIONAL_STARTUP_SERVICES="postgres valkey"
```
### 3.5 步骤5启动依赖服务
```bash
# 第56-73行如果存在需要启动的服务先启动它们
if [ ! -z "${ADDITIONAL_STARTUP_SERVICES// }" ]; then
COMPOSE_ARGS="\
-f docker-compose.yml ${ADDITIONAL_CACHE_ARGS} ${ADDITIONAL_COMPOSE_ARGS} ${ADDITIONAL_COMPOSE_QUEUE_ARGS} ${ADDITIONAL_COMPOSE_EDQS_ARGS} \
up -d ${ADDITIONUP_SERVICES}"
# 执行启动命令
docker compose $COMPOSE_ARGS
fi
```
**作用**
- 检查是否有需要先启动的服务(数据库、缓存)
- 如果有,先启动这些服务
- 使用 `up -d` 在后台启动,只启动指定的服务
**实际执行的命令示例**
```bash
docker compose \
-f docker-compose.yml \
-f docker-compose.valkey.yml \
-f docker-compose.postgres.yml \
-f docker-compose.kafka.yml \
up -d postgres valkey
```
**为什么先启动这些服务?**
- 数据库和缓存必须在 ThingsBoard 初始化之前运行
- ThingsBoard 安装时需要连接到数据库创建 schema
- 缓存服务也需要提前准备好
### 3.6 步骤6执行数据库初始化
```bash
# 第75-90行运行 tb-core1 容器执行安装
COMPOSE_ARGS="\
-f docker-compose.yml ${ADDITIONAL_CACHE_ARGS} ${ADDITIONAL_COMPOSE_ARGS} ${ADDITIONAL_COMPOSE_QUEUE_ARGS} ${ADDITIONAL_COMPOSE_EDQS_ARGS} \
run --no-deps --rm -e INSTALL_TB=true -e LOAD_DEMO=${loadDemo} \
tb-core1"
docker compose $COMPOSE_ARGS
```
**关键参数说明**
1. **`run`**: 运行一次性任务(不是启动服务)
2. **`--no-deps`**: 不启动依赖的服务因为已经在步骤5启动了
3. **`--rm`**: 容器运行完成后自动删除
4. **`-e INSTALL_TB=true`**: 设置环境变量,告诉启动脚本执行安装
5. **`-e LOAD_DEMO=${loadDemo}`**: 设置是否加载演示数据
6. **`tb-core1`**: 运行 tb-core1 服务容器
**实际执行的命令示例**
```bash
docker compose \
-f docker-compose.yml \
-f docker-compose.valkey.yml \
-f docker-compose.postgres.yml \
-f docker-compose.kafka.yml \
run --no-deps --rm \
-e INSTALL_TB=true \
-e LOAD_DEMO=false \
tb-core1
```
### 3.7 步骤7容器内的安装执行
`tb-core1` 容器启动时,会执行 `start-tb-node.sh` 脚本:
```bash
# start-tb-node.sh 中的逻辑第36-50行
if [ "$INSTALL_TB" == "true" ]; then
if [ "$LOAD_DEMO" == "true" ]; then
loadDemo=true
else
loadDemo=false
fi
echo "Starting ThingsBoard installation ..."
exec java -cp ${jarfile} $JAVA_OPTS \
-Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
-Dinstall.load_demo=${loadDemo} \
-Dinstall.upgrade=false \
-Dlogging.config=/usr/share/thingsboard/bin/install/logback.xml \
org.springframework.boot.loader.launch.PropertiesLauncher
fi
```
**作用**
- 检测到 `INSTALL_TB=true` 环境变量
- 调用 Java 应用程序 `ThingsboardInstallApplication`
- 执行数据库 schema 创建
- 如果 `LOAD_DEMO=true`,加载演示数据
**ThingsboardInstallApplication 做什么?**
1. 连接到 PostgreSQL 数据库
2. 执行 SQL 脚本创建所有表schema
3. 创建默认的租户、用户等基础数据
4. 如果 `load_demo=true`,加载演示设备、规则链等数据
5. 完成后退出
## 4. 完整执行流程图
```
用户执行: ./docker-install-tb.sh --loadDemo
├─ 1. 解析参数 → loadDemo=true
├─ 2. 加载工具函数 (compose-utils.sh)
├─ 3. 检测 Docker Compose 版本
├─ 4. 读取 .env 配置
│ ├─ DATABASE=postgres
│ ├─ CACHE=valkey
│ └─ TB_QUEUE_TYPE=kafka
├─ 5. 选择 Compose 文件
│ ├─ docker-compose.postgres.yml
│ ├─ docker-compose.valkey.yml
│ └─ docker-compose.kafka.yml
├─ 6. 启动依赖服务
│ └─ docker compose up -d postgres valkey
│ │
│ ├─ 启动 PostgreSQL 容器
│ └─ 启动 Valkey 容器
└─ 7. 执行数据库初始化
└─ docker compose run --no-deps --rm \
-e INSTALL_TB=true \
-e LOAD_DEMO=true \
tb-core1
└─ 容器内执行 start-tb-node.sh
└─ 检测到 INSTALL_TB=true
└─ 执行 Java 程序
└─ ThingsboardInstallApplication
├─ 连接 PostgreSQL
├─ 创建数据库表 (schema)
├─ 创建默认租户和用户
└─ 加载演示数据 (LOAD_DEMO=true)
└─ 完成后容器退出并删除
```
## 5. 关键环境变量
### 5.1 INSTALL_TB
**作用**:告诉启动脚本执行安装模式
**设置位置**`docker-install-tb.sh` 第77行
```bash
-e INSTALL_TB=true
```
**检测位置**`start-tb-node.sh` 第36行
```bash
if [ "$INSTALL_TB" == "true" ]; then
# 执行安装
fi
```
### 5.2 LOAD_DEMO
**作用**:控制是否加载演示数据
**设置位置**`docker-install-tb.sh` 第77行
```bash
-e LOAD_DEMO=${loadDemo}
```
**传递到 Java**`start-tb-node.sh` 第47行
```bash
-Dinstall.load_demo=${loadDemo}
```
## 6. 为什么使用 `run` 而不是 `up`
### 6.1 `docker compose run` vs `docker compose up`
**`docker compose up`**:
- 启动服务并保持运行
- 服务会一直运行直到停止
- 用于启动长期运行的服务
**`docker compose run`**:
- 运行一次性任务
- 任务完成后容器退出
- 配合 `--rm` 可以自动清理容器
- 用于执行初始化、升级等一次性操作
### 6.2 为什么适合安装场景?
安装是一个**一次性任务**
- ✅ 执行完数据库初始化就完成了
- ✅ 不需要容器一直运行
- ✅ 使用 `run` 更合适
如果使用 `up`
- ❌ 容器会一直运行
- ❌ 需要手动停止和删除
- ❌ 不符合安装的使用场景
## 7. `--no-deps` 的作用
### 7.1 默认行为
默认情况下,`docker compose run` 会:
1. 检查服务的依赖(`depends_on`
2. 自动启动依赖的服务
### 7.2 为什么使用 `--no-deps`
`docker-install-tb.sh` 中:
1. **步骤5**已经手动启动了依赖服务(数据库、缓存)
2. **步骤6**不需要再次启动这些服务
3. 使用 `--no-deps` 避免重复启动
**好处**
- ✅ 避免重复启动服务
- ✅ 确保依赖服务已经在运行
- ✅ 更精确的控制启动顺序
## 8. 实际执行示例
### 8.1 不加载演示数据
```bash
$ ./docker-install-tb.sh
# 步骤1: 启动依赖服务
docker compose \
-f docker-compose.yml \
-f docker-compose.postgres.yml \
-f docker-compose.valkey.yml \
-f docker-compose.kafka.yml \
up -d postgres valkey
# 步骤2: 执行安装
docker compose \
-f docker-compose.yml \
-f docker-compose.postgres.yml \
-f docker-compose.valkey.yml \
-f docker-compose.kafka.yml \
run --no-deps --rm \
-e INSTALL_TB=true \
-e LOAD_DEMO=false \
tb-core1
# 输出:
# Starting ThingsBoard installation ...
# Creating database schema...
# Creating default tenant...
# Installation completed successfully!
```
### 8.2 加载演示数据
```bash
$ ./docker-install-tb.sh --loadDemo
# 步骤相同,但 LOAD_DEMO=true
# 输出:
# Starting ThingsBoard installation ...
# Creating database schema...
# Creating default tenant...
# Loading demo data...
# - Demo devices...
# - Demo dashboards...
# - Demo rule chains...
# Installation completed successfully!
```
## 9. 注意事项
### 9.1 首次安装前
1. **创建日志目录**
```bash
./docker-create-log-folders.sh
```
2. **配置 .env 文件**
```bash
DATABASE=postgres
CACHE=valkey
TB_QUEUE_TYPE=kafka
```
### 9.2 安装后
1. **不要重复执行**:数据库 schema 已经创建,重复执行可能会报错
2. **检查日志**:如果安装失败,查看容器日志
```bash
docker compose logs tb-core1
```
### 9.3 常见问题
**问题1数据库连接失败**
**原因**PostgreSQL 服务还没完全启动
**解决**:等待几秒后重试,或检查 PostgreSQL 日志
```bash
docker compose logs postgres
```
**问题2Schema 已存在错误**
**原因**:数据库已经初始化过了
**解决**:如果需要重新安装,先删除数据库数据
```bash
docker compose down -v # 删除所有数据卷
./docker-install-tb.sh # 重新安装
```
## 10. 与其他脚本的关系
### 10.1 docker-create-log-folders.sh
**执行顺序**:在 `docker-install-tb.sh` **之前**执行
**作用**:创建日志目录并设置权限
### 10.2 docker-start-services.sh
**执行顺序**:在 `docker-install-tb.sh` **之后**执行
**作用**:启动所有 ThingsBoard 服务
**完整流程**
```bash
# 1. 创建日志目录
./docker-create-log-folders.sh
# 2. 初始化数据库
./docker-install-tb.sh --loadDemo
# 3. 启动所有服务
./docker-start-services.sh
```
## 11. 总结
### 11.1 脚本的核心作用
`docker-install-tb.sh` 是一个**数据库初始化脚本**,它:
1.**启动依赖服务**:确保数据库和缓存服务运行
2.**执行数据库初始化**:创建数据库 schema 和基础数据
3.**可选加载演示数据**:方便快速体验和测试
### 11.2 关键设计
- **分离关注点**:依赖服务启动和数据库初始化分开
- **一次性任务**:使用 `run` 而不是 `up`
- **自动清理**:使用 `--rm` 自动删除临时容器
- **灵活配置**:根据 `.env` 选择不同的配置组合
### 11.3 使用场景
-**首次部署**:创建数据库 schema
-**测试环境**:快速搭建带演示数据的环境
-**开发环境**:快速初始化开发数据库
**注意**:这个脚本**只在首次安装时使用**,后续启动服务使用 `docker-start-services.sh`