如何在Ubuntu/Mysql Docker容器中完成库准备、测试执行并自动退出
问题与解决方案
问题描述
无法实现完整流程:启动ubuntu/mysql容器、完成数据库初始化、执行测试脚本后自动退出容器。当前配置如下:
Dockerfile内容:
FROM ubuntu/mysql:latest COPY my_db_scripts.sql /docker-entrypoint-initdb.d/ COPY my_test.sh /tests WORKDIR /tests
运行命令:
docker run --rm -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=cool my_tests:1.0.0
遇到的问题:
- 将
my_test.sh设为ENTRYPOINT/CMD时,脚本会在MySQL监听器启动前执行,导致测试失败; - 把脚本放入
/docker-entrypoint-initdb.d/目录,脚本会在临时MySQL实例停止后执行,不符合测试时机需求(官方文档说明:所有该目录下的操作都在MySQL服务启动前完成)。
需求:等待MySQL完全启动就绪后执行my_test.sh,测试完成后容器自动停止(脚本根据测试结果返回对应错误码)。
解决方案
方案一:自定义Entrypoint脚本,继承官方启动流程
该方案通过自定义entrypoint脚本,先执行官方镜像的初始化流程,等待MySQL就绪后再执行测试,最后停止服务让容器退出。
- 创建自定义entrypoint脚本
custom-entrypoint.sh:
#!/bin/bash set -e # 启动官方entrypoint流程(完成数据库初始化并启动MySQL) /usr/local/bin/docker-entrypoint.sh mysqld & # 等待MySQL服务就绪 until mysqladmin ping -h"localhost" -u"root" -p"$MYSQL_ROOT_PASSWORD" --silent; do echo "等待MySQL启动..." sleep 2 done # 执行测试脚本 echo "MySQL已就绪,开始执行测试..." /tests/my_test.sh # 测试完成后停止MySQL,触发容器退出 mysqladmin shutdown -u"root" -p"$MYSQL_ROOT_PASSWORD"
- 修改Dockerfile:
FROM ubuntu/mysql:latest COPY my_db_scripts.sql /docker-entrypoint-initdb.d/ COPY my_test.sh /tests COPY custom-entrypoint.sh /usr/local/bin/ # 给脚本添加可执行权限 RUN chmod +x /usr/local/bin/custom-entrypoint.sh /tests/my_test.sh WORKDIR /tests ENTRYPOINT ["custom-entrypoint.sh"]
- 构建并运行容器:
docker build -t my_tests:1.0.0 . docker run --rm -e MYSQL_ROOT_PASSWORD=cool my_tests:1.0.0
方案二:修改测试脚本,加入等待逻辑
直接在测试脚本中加入等待MySQL就绪的代码,测试完成后主动停止MySQL服务。
- 修改
my_test.sh:
#!/bin/bash set -e # 等待MySQL服务可用 echo "等待MySQL启动..." until mysql -h"localhost" -u"root" -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1;" >/dev/null 2>&1; do sleep 2 done # 此处编写你的测试逻辑 echo "开始执行测试..." # 示例:查询数据库列表 mysql -h"localhost" -u"root" -p"$MYSQL_ROOT_PASSWORD" -e "SHOW DATABASES;" # 其他测试步骤... # 测试完成后停止MySQL,容器随主进程退出 mysqladmin shutdown -u"root" -p"$MYSQL_ROOT_PASSWORD"
- 修改Dockerfile:
FROM ubuntu/mysql:latest COPY my_db_scripts.sql /docker-entrypoint-initdb.d/ COPY my_test.sh /tests RUN chmod +x /tests/my_test.sh WORKDIR /tests CMD ["bash", "/tests/my_test.sh"]
- 构建并运行容器:
docker build -t my_tests:1.0.0 . docker run --rm -e MYSQL_ROOT_PASSWORD=cool my_tests:1.0.0
注意事项
- 使用
mysqladmin ping或mysql -e "SELECT 1"是检测MySQL就绪的可靠方式,避免使用单纯的端口检测; - 测试完成后必须调用
mysqladmin shutdown停止MySQL服务,否则容器会一直运行; - 若在CI/CD环境中运行,可去掉
docker run命令中的-it参数,实现无交互自动执行; - 确保所有脚本都添加了可执行权限,否则会执行失败。
内容的提问来源于stack exchange,提问作者angryip
相关产品推荐
相关产品推荐

