我正在部署一些不同的docker容器,mysql是第一个.我想在数据库启动后立即运行脚本并继续构建其他容器.该脚本一直在失败,因为当设置mysql(来自这个官方的mysql容器)的入口点脚本仍在运行时,它试图运行.
sudo docker run --name mysql -e MYSQL_ROOT_PASSWORD=MY_ROOT_PASS -p 3306:3306 -d mysql [..] wait for mysql to be ready [..] mysql -h 127.0.0.1 -P 3306 -u root --password=MY_ROOT_PASS < MY_SQL_SCRIPT.sql
有没有办法等待在docker容器内完成入门的mysql安装脚本的信号?Bash睡眠似乎是次优解决方案.
编辑:去找这样的bash脚本.不是最优雅和善良的蛮力,但工作就像一个魅力.也许有人会觉得有用.
OUTPUT="Can't connect" while [[ $OUTPUT == *"Can't connect"* ]] do OUTPUT=$(mysql -h $APP_IP -P :$APP_PORT -u yyy --password=xxx < ./my_script.sql 2>&1) done
flamemyst.. 49
您可以安装mysql-client软件包并使用mysqladmin来ping目标服务器.使用多个docker容器时很有用.结合sleep并创建一个简单的等待循环:
while ! mysqladmin ping -h"$DB_HOST" --silent; do sleep 1 done
这是一件美好的事情.对于Docker健康检查也很有用:`docker run --health-cmd ='mysqladmin ping --silent'-d mysql` (20认同)
为了等待单位容器是健康的我使用脚本`while [$(docker inspect --format"{{json .State.Health.Status}}"
这在这里不起作用; 我真的可以使用数据库之前`mysqladmin ping`成功 - 我想容器仍在运行的是初始化`.sql`脚本. (4认同)
小智.. 32
这个小的bash循环等待mysql打开,不需要安装任何额外的包:
until nc -z -v -w30 $CFG_MYSQL_HOST 3306 do echo "Waiting for database connection..." # wait for 5 seconds before check again sleep 5 done
仅仅因为端口可用并不意味着服务器已准备好接受连接.`mysqladmin ping`就是这里的正确答案. (5认同)
好一个.我用它作为1个班轮:直到nc -z $ CFG_MYSQL_HOST 3306; 做睡觉1; 回声"等待DB出现......"; DONE (2认同)
Andrew Savin.. 24
在其他答案的评论中或多或少地提到了这一点,但我认为它应该是它自己的条目.
首先,您可以按以下方式运行容器:
docker run --name mysql --health-cmd='mysqladmin ping --silent' -d mysql
Dockerfile中还有一个等价物.
与该命令你docker ps
,并docker inspect
会告诉你你的容器的健康状况.特别是对于mysql,此方法具有在容器内mysqladmin
可用的优点,因此您无需在docker主机上安装它.
然后你可以简单地循环一个bash脚本来等待状态变得健康.以下bash脚本由Dennis创建.
function getContainerHealth { docker inspect --format "{{json .State.Health.Status }}" $1 } function waitContainer { while STATUS=$(getContainerHealth $1); [ $STATUS != "\"healthy\"" ]; do if [ $STATUS == "\"unhealthy\"" ]; then echo "Failed!" exit -1 fi printf . lf=$'\n' sleep 1 done printf "$lf" }
现在您可以在脚本中执行此操作:
waitContainer mysql
并且您的脚本将一直等到容器启动并运行.如果容器变得不健康,脚本将退出,这是可能的,如果例如docker host内存不足,那么mysql无法为自己分配足够的内容.