如何在Cassandra的Dockerfile中运行Flyway或CQL迁移脚本?
问题根因
- 核心错误是覆盖了官方镜像的默认启动逻辑:
cassandra:4.0官方镜像自带的入口程序会完成Cassandra服务启动、初始化配置等操作,你直接将CMD替换为自定义的entrypoint.sh后,容器启动后只会运行你的检测脚本,根本不会启动Cassandra服务,自然无法建立连接。 - 可选小问题:你自定义的
CQLVERSION默认值设为4.0可能和实际Cassandra支持的CQL版本不匹配,Cassandra 4.0对应的原生CQL版本为3.4.5,版本不匹配也会导致cqlsh连接失败。
解决方案
方案1:使用官方原生初始化机制(推荐)
官方Cassandra镜像预留了自动初始化目录/docker-entrypoint-initdb.d/,所有放在该目录下的.cql、.sh文件都会在Cassandra首次启动、初始化完成后自动执行,无需自行编写连接检测逻辑,修改后的Dockerfile如下:
FROM cassandra:4.0 MAINTAINER me # 直接将cql脚本复制到初始化目录 COPY alter.cql /docker-entrypoint-initdb.d/ RUN chmod 644 /docker-entrypoint-initdb.d/alter.cql EXPOSE 9042 # 无需修改默认的ENTRYPOINT/CMD配置
该方案不会破坏镜像原有的启动逻辑,且初始化脚本只会在容器首次启动(数据卷未初始化)时执行,后续重启不会重复运行,符合Cassandra的常规使用需求。
方案2:调整自定义入口脚本逻辑
如果确实需要保留自定义入口脚本实现额外逻辑,需要先启动Cassandra服务再执行初始化操作,修改entrypoint.sh内容如下:
#!/bin/bash # 后台启动官方自带的Cassandra入口逻辑 /docker-entrypoint.sh cassandra & CASSANDRA_PID=$! # 调整为Cassandra 4.0对应的正确CQL版本 export CQLVERSION=${CQLVERSION:-"3.4.5"} export CQLSH_HOST=${CQLSH_HOST:-"localhost"} export CQLSH_PORT=${CQLSH_PORT:-"9042"} cqlsh=( cqlsh --cqlversion ${CQLVERSION} ) # 测试Cassandra连接 echo "Checking connection to cassandra..." for i in {1..30}; do if "${cqlsh[@]}" -e "show host;" 2> /dev/null; then break fi echo "Can't establish connection, will retry again in $i seconds" sleep $i done if [ "$i" = 30 ]; then echo >&2 "Failed to connect to cassandra at ${CQLSH_HOST}:${CQLSH_PORT}" kill $CASSANDRA_PID exit 1 fi # 执行所有cql脚本 for file in /scripts/*.cql; do [ -e "$file" ] || continue echo "Executing $file..." "${cqlsh[@]}" -f "$file" done echo "Done." # 前台阻塞Cassandra进程,避免容器退出 wait $CASSANDRA_PID
修改后的Dockerfile如下:
FROM cassandra:4.0 MAINTAINER me ADD entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod 755 /usr/local/bin/entrypoint.sh RUN mkdir -p /scripts COPY alter.cql /scripts/ RUN chmod 644 /scripts/alter.cql EXPOSE 9042 ENTRYPOINT ["entrypoint.sh"]
内容的提问来源于stack exchange,提问作者Ankush Virmani
相关产品推荐
相关产品推荐

