记一次 StreamPark 2.1.5 Docker 部署 MySQL 的完整踩坑与排查记录摘要使用 Docker 部署 Apache StreamPark 2.1.5官方文档和网上教程都说「设置环境变量SPRING_PROFILES_ACTIVEmysqlMYSQL_*就能连 MySQL」结果怎么配都是 H2数据一重启就丢。本文完整记录从「现象」到「根因」再到「解决」的全过程。一、背景与问题现象我需要在测试服务器上用 Docker 部署 StreamPark 来管理 Flink 集群后端元数据库用 MySQL。按照网上常见的 docker-compose 写法给 StreamPark 服务配了这些环境变量environment:SPRING_PROFILES_ACTIVE:mysqlMYSQL_HOST:mysqlMYSQL_PORT:3306MYSQL_USERNAME:streamparkMYSQL_PASSWORD:xxxxxxMYSQL_DATABASE:streampark启动后 StreamPark 能正常打开、也能登录一切都「看起来」正常。直到有一天我改了 compose 配置加了个 Flink Home 挂载docker stop后docker compose up -d重启重启后发现之前配置的 team团队全没了连进 MySQL 一看streampark库里一张表都没有。这就很奇怪了——明明配的是 MySQL怎么数据会丢MySQL 里怎么连表都没有二、排查过程第一步确认 StreamPark 到底连的是哪个库看启动日志里数据源相关的内容dockerlogs streampark21|grep-iEjdbc:h2|jdbc:mysql|HikariPool|datasource日志里出现H2 console available at /h2-console. Database available at jdbc:h2:file:~/streampark/h2-data/metadata结论StreamPark 根本没连 MySQL一直在用 H2 内嵌库。数据存在容器里的~/streampark/h2-data目录容器一重建就丢所以 team 没了、MySQL 里自然也没表。第二步环境变量明明设了为什么没用确认环境变量确实注入了容器dockerexecstreamparkenv|grep-iESPRING|MYSQL输出SPRING_PROFILES_ACTIVEmysql MYSQL_HOSTmysql MYSQL_PORT3306 MYSQL_USERNAMEstreampark MYSQL_PASSWORDxxxxxx MYSQL_DATABASEstreampark变量都在但就是没用。于是又尝试了两条更「强力」的方式尝试一用 Spring Boot 原生的SPRING_DATASOURCE_*环境变量。在docker-compose-streampark.yml的streampark服务里新增这 4 个变量Spring Boot 对spring.datasource.url/username/password有 relaxed binding会自动映射environment:TZ:${TZ}SPRING_PROFILES_ACTIVE:mysqlSPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/streampark?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueSPRING_DATASOURCE_USERNAME:${MYSQL_USER}SPRING_DATASOURCE_PASSWORD:${MYSQL_PASSWORD}SPRING_DATASOURCE_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.DriverMYSQL_HOST:mysqlMYSQL_PORT:3306MYSQL_USERNAME:${MYSQL_USER}MYSQL_PASSWORD:${MYSQL_PASSWORD}MYSQL_DATABASE:${MYSQL_DATABASE}重启后依旧 H2。尝试二用JAVA_TOOL_OPTIONS注入 JVM 系统属性优先级比环境变量更高。同样在environment里加一行JAVA_TOOL_OPTIONS:-Dspring.profiles.activemysql -Dspring.datasource.urljdbc:mysql://mysql:3306/streampark?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue -Dspring.datasource.username${MYSQL_USER} -Dspring.datasource.password${MYSQL_PASSWORD} -Dspring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver重启后日志里能看到Picked up JAVA_TOOL_OPTIONS: -Dspring.profiles.activemysql -Dspring.datasource.urljdbc:mysql://...说明 JVM 确实收到了这些-D参数但StreamPark 依旧用 H2。到这里基本可以判断这不是 Spring Boot 标准的数据源配置StreamPark 走了另一套配置。第三步找到真正的启动入口和配置文件查容器的入口dockerinspect streampark--format{{json .Config.Entrypoint}}# [/usr/sbin/tini,--,/streampark/bin/streampark.sh,start_docker]入口是/streampark/bin/streampark.sh start_docker。查看容器目录发现关键目录/streampark/conf/下有个config.yamldockerexecstreamparkls-la/streampark/conf/# config.yaml# logback-spring.xml打开config.yaml真相大白datasource:dialect:h2#h2, mysql, pgsqlh2-data-dir:~/streampark/h2-datausername:password:url:StreamPark 的真实数据库配置在config.yaml的datasource.dialect跟环境变量、Spring profile 一点关系都没有。默认是h2所以上面那些SPRING_PROFILES_ACTIVE、MYSQL_*、JAVA_TOOL_OPTIONS全都在做无用功。第四步改 config.yaml 后遇到第二个坑——MySQL 驱动找不到先把容器里原本的 config.yaml 完整拉取下来只改 datasource 这一段mkdir-p/data/streampark/streampark-confdockercpstreampark:/streampark/conf/config.yaml /data/streampark/streampark-conf/config.yaml打开后找到 datasource 段。改前datasource:dialect:h2#h2, mysql, pgsqlh2-data-dir:~/streampark/h2-datausername:password:url:改成其余部分保持不动datasource:dialect:mysql#h2, mysql, pgsqlh2-data-dir:~/streampark/h2-data# 仅在 dialecth2 时生效username:streamparkpassword:xxxxxxurl:jdbc:mysql://mysql:3306/streampark?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue然后在docker-compose-streampark.yml的streampark服务里加挂载把改好的配置覆盖回容器volumes:-/data/streampark/streampark-conf/config.yaml:/streampark/conf/config.yaml重启后报错The datasource.dialect is MySQL, but the classes com.mysql.cj.jdbc.Driver and com.mysql.jdbc.Driver not found. Please ensure that the MySQL Connector/J is located under $streampark/lib. Note: The MySQL Connector/J is not compatible with the Apache 2.0 license.原因MySQL Connector/J 是 GPL 许可与 Apache 2.0 不兼容所以 StreamPark 官方镜像故意不内置MySQL 驱动需要自己下载放进/streampark/lib/。下载并挂载wget-O/data/streampark/mysql-connector-j-8.0.33.jar\https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jarcompose 里加挂载volumes:-/data/streampark/mysql-connector-j-8.0.33.jar:/streampark/lib/mysql-connector-j-8.0.33.jar第五步第三个坑——MySQL 不会自动建表驱动和连接都好了重启又报java.sql.SQLSyntaxErrorException: Table streampark.t_flink_app doesnt exist原因StreamPark 对H2内嵌库会自动建表但对MySQL外部库不会自动建表需要手动导入建表脚本。建表脚本在哪在容器里dockerexecstreamparkfind/streampark-name*.sql2/dev/null# /streampark/script/schema/mysql-schema.sql# /streampark/script/data/mysql-data.sql小技巧如果 StreamPark 配了 MySQL 但没表会一直 crash-loop 起不来docker exec根本进不去、也拿不到文件。这时可以先注释掉 config.yaml 挂载让它退回 H2 正常启动拿到 SQL 文件后再恢复。导入 SQL先建表后插初始数据dockercpstreampark:/streampark/script/schema/mysql-schema.sql /data/streampark/mysql-schema.sqldockercpstreampark:/streampark/script/data/mysql-data.sql /data/streampark/mysql-data.sqldockerexec-istreampark-mysql mysql-ustreampark-p密码streampark/data/streampark/mysql-schema.sqldockerexec-istreampark-mysql mysql-ustreampark-p密码streampark/data/streampark/mysql-data.sql验证dockerexecstreampark-mysql mysql-ustreampark-p密码streampark-eSHOW TABLES;看到一堆t_开头的表重启 StreamPark终于正常起来了。三、根因总结StreamPark 2.1.5 用 Docker 部署时连不上 MySQL其实是三个独立的坑叠加#坑说明1配置读 config.yaml不读环境变量SPRING_PROFILES_ACTIVE、MYSQL_*、SPRING_DATASOURCE_*、JAVA_TOOL_OPTIONS全都无效只有/streampark/conf/config.yaml的datasource.dialect说了算2镜像不内置 MySQL 驱动GPL 许可与 Apache 2.0 冲突需自备mysql-connector-j挂进/streampark/lib/3MySQL 不自动建表只有 H2 内嵌库会自动建表MySQL 需手动导mysql-schema.sqlmysql-data.sql四、完整解决方案可直接复制1. 准备 config.yamlMySQL 版datasource:dialect:mysqlusername:streamparkpassword:你的密码url:jdbc:mysql://mysql:3306/streampark?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue2. 下载 MySQL 驱动wget-O/data/streampark/mysql-connector-j-8.0.33.jar\https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar3. compose 里挂载config.yaml 驱动 Flink Homestreampark:image:apache/streampark:2.1.4# 建议 2.1.42.1.5 镜像对 MySQL 支持有问题volumes:-/data/streampark/streampark-conf/config.yaml:/streampark/conf/config.yaml-/data/streampark/mysql-connector-j-8.0.33.jar:/streampark/lib/mysql-connector-j-8.0.33.jar-/data/streampark/flink-1.18.1/flink:/opt/flink# 可选Flink Home4. 导入建表 SQLdockerexec-istreampark-mysql mysql-ustreampark-p密码streampark/data/streampark/mysql-schema.sqldockerexec-istreampark-mysql mysql-ustreampark-p密码streampark/data/streampark/mysql-data.sql5. 启动验证dockercompose-fdocker-compose-streampark.yml up-ddockerexecstreampark-mysql mysql-ustreampark-p密码streampark-eSHOW TABLES;五、总结这次排查给我最大的教训是遇到「配置了却无效」的问题不要一直往环境变量/启动参数上使劲先找到这个应用真正读的是哪个配置文件。StreamPark 的 Docker 镜像有几个「反直觉」的设计数据库配置在config.yaml里环境变量是「障眼法」MySQL 驱动要自己放官方不内置GPL 许可原因MySQL 要手动建表不像 H2 那样开箱即用。希望这篇记录能帮到同样踩坑的人少走弯路。附完整排障命令速查# 看连的是哪个库dockerlogs streampark21|grep-iEjdbc:h2|jdbc:mysql|HikariPool|tail-50# 看真实配置dockerexecstreamparkcat/streampark/conf/config.yaml# 看入口脚本dockerinspect streampark--format{{json .Config.Entrypoint}}# 在容器里找 SQL 脚本dockerexecstreamparkfind/streampark-name*.sql2/dev/null# 验证 MySQL 表dockerexecstreampark-mysql mysql-ustreampark-p密码streampark-eSHOW TABLES;