# 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 ``` **问题2:Schema 已存在错误** **原因**:数据库已经初始化过了 **解决**:如果需要重新安装,先删除数据库数据 ```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`!