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

477 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`