# ThingsBoard Docker 镜像构建流程分析 ## 1. 概述 ThingsBoard 的 Docker 镜像构建采用 Maven + Dockerfile 的方式,先通过 Maven 编译源码并打包成 DEB 包,然后使用 Dockerfile 将 DEB 包安装到 Docker 镜像中。 ## 2. 构建流程总览 ``` 源码编译 -> Maven 打包 -> DEB 包生成 -> Dockerfile 构建 -> Docker 镜像 ``` ## 3. 核心组件构建流程 ### 3.1 tb-node (核心服务/规则引擎) **位置**: `msa/tb-node/` #### 3.1.1 Maven 构建配置 **文件**: `msa/tb-node/pom.xml` **关键步骤**: 1. **依赖 DEB 包**: ```xml org.thingsboard application ${project.version} deb deb provided ``` 2. **复制 DEB 包到构建目录**: ```xml org.apache.maven.plugins maven-dependency-plugin copy-tb-deb package copy org.thingsboard application deb deb ${pkg.name}.deb ${project.build.directory} ``` 3. **复制 Docker 配置文件**: ```xml org.apache.maven.plugins maven-resources-plugin copy-docker-config process-resources copy-resources ${project.build.directory} docker true ``` 4. **构建 Docker 镜像**: ```xml com.spotify dockerfile-maven-plugin build-docker-image pre-integration-test build ${dockerfile.skip} ${docker.repo}/${docker.name} true ${project.build.directory} ``` #### 3.1.2 Dockerfile **文件**: `msa/tb-node/docker/Dockerfile` ```dockerfile # 基础镜像:OpenJDK 17 FROM thingsboard/openjdk17:bookworm-slim # 复制文件到临时目录 COPY logback.xml start-tb-node.sh ${pkg.name}.deb /tmp/ # 安装 DEB 包并配置 RUN chmod a+x /tmp/*.sh \ && mv /tmp/start-tb-node.sh /usr/bin && \ (yes | dpkg -i /tmp/${pkg.name}.deb) && \ rm /tmp/${pkg.name}.deb && \ mv /tmp/logback.xml ${pkg.installFolder}/conf && \ chown -R ${pkg.user}:${pkg.user} ${pkg.installFolder}/conf/logback.xml && \ (systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || :) && \ chown -R ${pkg.user}:${pkg.user} /tmp && \ chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar USER ${pkg.user} CMD ["start-tb-node.sh"] ``` **关键点**: - 使用 `dpkg -i` 安装 DEB 包 - DEB 包会将应用安装到 `/usr/share/thingsboard/` - 复制启动脚本和配置文件 - 设置正确的用户权限 #### 3.1.3 DEB 包生成 **位置**: `application/pom.xml` 和 `packaging/java/` DEB 包是通过 Gradle 构建的: 1. **Gradle 构建脚本**: `packaging/java/build.gradle` 2. **构建阶段**: 在 Maven 的 `package` 阶段调用 Gradle 3. **输出**: `application/target/thingsboard-{version}-boot.deb` DEB 包包含: - JAR 文件(Spring Boot 打包的应用) - 配置文件 - 启动脚本 - 系统服务文件 ### 3.2 传输服务 (MQTT/HTTP/CoAP/LWM2M/SNMP) **位置**: `msa/transport/{protocol}/` #### 3.2.1 Maven 构建配置 **文件**: `msa/transport/mqtt/pom.xml` (以 MQTT 为例) **关键步骤**: 1. **依赖传输模块的 DEB 包**: ```xml org.thingsboard.transport mqtt ${project.version} deb deb provided ``` 2. **复制 DEB 包**: ```xml copy-tb-mqtt-transport-deb package copy org.thingsboard.transport mqtt deb deb ${pkg.name}.deb ${project.build.directory} ``` 3. **构建 Docker 镜像**: 与 tb-node 类似 #### 3.2.2 传输模块 DEB 包生成 **位置**: `transport/mqtt/pom.xml` 传输模块的 DEB 包也是通过 Gradle 构建的,构建流程与 application 模块类似。 ### 3.3 Web UI 服务 **位置**: `msa/web-ui/` #### 3.3.1 构建流程 **文件**: `msa/web-ui/pom.xml` **关键步骤**: 1. **前端构建**: ```xml com.github.eirslett frontend-maven-plugin install node and yarn install-node-and-yarn v22.18.0 v1.22.22 yarn install yarn install --non-interactive yarn pkg yarn compile run pkg ``` 2. **提取 UI 文件**: ```xml extract-web-ui unpack org.thingsboard ui-ngx jar ${project.build.directory}/web ``` 3. **Dockerfile**: 使用 Node.js 基础镜像,运行前端服务 ### 3.4 JS Executor 服务 **位置**: `msa/js-executor/` #### 3.4.1 Dockerfile **文件**: `msa/js-executor/docker/Dockerfile` ```dockerfile FROM thingsboard/node:22.18.0-bookworm-slim ENV NODE_ENV production ENV DOCKER_MODE true COPY start-js-executor.sh /tmp/ WORKDIR ${pkg.installFolder} # 复制源代码和配置文件 COPY ["src/package.json", "src/yarn.lock", "./"] COPY package/linux/conf ./conf COPY package/linux/conf ./config COPY src/api ./api COPY src/queue ./queue COPY src/config ./config COPY src/server.js ./ # 安装依赖并设置权限 RUN chmod a+x /tmp/*.sh \ && mv /tmp/start-js-executor.sh /usr/bin \ && chown -R node:node ${pkg.installFolder} \ && yarn install --production --non-interactive \ && yarn cache clean --all USER node CMD ["start-js-executor.sh"] ``` **特点**: JS Executor 直接复制源代码,不需要 DEB 包。 ## 4. 完整构建命令 ### 4.1 构建所有组件 ```bash # 从项目根目录执行 ./build.sh # 或者使用 Maven mvn clean install -DskipTests ``` ### 4.2 构建特定组件 ```bash # 构建特定模块 ./build.sh msa/tb-node,msa/web-ui # 或者 mvn clean install -DskipTests --projects msa/tb-node,msa/web-ui ``` ### 4.3 构建并推送 Docker 镜像 ```bash # 构建并推送镜像 mvn clean install -DskipTests -Ddockerfile.skip=false -Dpush-docker-image=true ``` ## 5. 构建依赖关系 ### 5.1 模块依赖顺序 ``` 1. common/* (公共模块) ↓ 2. dao (数据访问层) ↓ 3. application (主应用) ↓ 4. transport/* (传输模块) ↓ 5. ui-ngx (前端) ↓ 6. msa/* (微服务镜像) ``` ### 5.2 DEB 包生成顺序 1. **application 模块**: 生成 `thingsboard-{version}-boot.deb` 2. **transport 模块**: 生成 `tb-{protocol}-transport-{version}.deb` 3. **ui-ngx 模块**: 生成 JAR 包(包含前端静态资源) ## 6. 构建产物位置 ### 6.1 DEB 包 - **Application**: `application/target/thingsboard-{version}-boot.deb` - **Transport**: `transport/{protocol}/target/tb-{protocol}-transport-{version}.deb` ### 6.2 Docker 镜像构建上下文 - **tb-node**: `msa/tb-node/target/` - 包含: Dockerfile, DEB 包, 启动脚本, 配置文件 - **传输服务**: `msa/transport/{protocol}/target/` - 包含: Dockerfile, DEB 包, 启动脚本 ### 6.3 Docker 镜像 构建完成后,Docker 镜像会保存在本地: - `thingsboard/tb-node:{version}` - `thingsboard/tb-mqtt-transport:{version}` - `thingsboard/tb-web-ui:{version}` - 等等 ## 7. 构建脚本详解 ### 7.1 build.sh **位置**: `build.sh` ```bash #!/bin/bash # 设置错误时退出 set -e # 可以指定要构建的项目 PROJECTS="" if [ "$1" ]; then PROJECTS="--projects $1" fi # 构建命令 MAVEN_OPTS="-Xmx1024m" NODE_OPTIONS="--max_old_space_size=4096" \ DOCKER_CLI_EXPERIMENTAL=enabled DOCKER_BUILDKIT=0 \ mvn -T2 license:format clean install -DskipTests \ $PROJECTS --also-make ``` **关键参数**: - `-T2`: 使用 2 个线程并行构建 - `--also-make`: 同时构建依赖模块 - `-DskipTests`: 跳过测试(加快构建速度) ## 8. 构建环境要求 ### 8.1 必需工具 - **Java 17**: 编译 Java 代码 - **Maven 3.6+**: 构建工具 - **Docker**: 构建 Docker 镜像 - **Node.js 22.18.0**: 构建前端(web-ui) - **Yarn 1.22.22**: 前端包管理 ### 8.2 系统要求 - **内存**: 至少 4GB(推荐 8GB+) - **磁盘空间**: 至少 10GB 可用空间 - **操作系统**: Linux/macOS(Windows 需要 WSL) ## 9. 构建优化 ### 9.1 并行构建 ```bash # 使用多线程构建 mvn -T4 clean install -DskipTests ``` ### 9.2 跳过 Docker 构建 ```bash # 只构建代码,不构建 Docker 镜像 mvn clean install -DskipTests -Ddockerfile.skip=true ``` ### 9.3 增量构建 ```bash # 只构建变更的模块 mvn clean install -DskipTests --projects msa/tb-node ``` ## 10. 常见问题 ### 10.1 DEB 包找不到 **原因**: application 模块没有先构建 **解决**: 先构建 application 模块 ```bash mvn clean install -DskipTests --projects application ``` ### 10.2 Docker 构建失败 **原因**: Docker daemon 未运行或权限不足 **解决**: ```bash # 检查 Docker 状态 docker ps # 确保用户在 docker 组中 sudo usermod -aG docker $USER ``` ### 10.3 前端构建失败 **原因**: Node.js 版本不匹配或网络问题 **解决**: ```bash # 使用正确的 Node.js 版本 nvm use 22.18.0 # 清理缓存重试 cd ui-ngx && rm -rf node_modules && yarn install ``` ## 11. 总结 ThingsBoard 的 Docker 镜像构建流程: 1. **源码编译**: Maven 编译 Java 代码 2. **打包**: 使用 Gradle 打包成 DEB 包(Java 服务)或 JAR 包(前端) 3. **Docker 构建**: 使用 dockerfile-maven-plugin 调用 Dockerfile 构建镜像 4. **镜像生成**: 最终生成 Docker 镜像 **关键特点**: - 使用 DEB 包作为中间产物,便于安装和配置 - 采用 Maven 多模块项目结构,支持并行构建 - 前端和 Java 服务采用不同的构建方式 - 支持构建特定模块,提高构建效率 通过这个流程,ThingsBoard 可以将复杂的多模块项目统一构建成 Docker 镜像,便于部署和管理。