我正在尝试创建一个mariadb容器,并希望在开始时启动SQL脚本。
基础Dockerfile
FROM mariadb:10.5.6
# Copy a "creation.sql" script to the container
COPY /sql/* /sql/
手工执行工作
如果我在容器启动后等待10-20秒,然后执行命令行docker exec -it my_container_name mysql -e "source sql/creation.sql;" -uroot -pMyPasswordHere
,那么脚本就可以正常运行。但我宁愿有这部分的构建或运行过程,而不是需要手动步骤和等待时间的猜测。
运行-不工作
我尝试在Dockerfile中使用RUN
:
RUN mysql -e "source sql/creation.sql;" -uroot -p$MYSQL_ROOT_PASSWORD`
但它失败了:* 构建过程中无法通过socket* 连接到本地MySQL服务器。我假设这是因为服务尚未启动。
CMD -不工作
我还尝试使用ENTRYPOINT
和CMD
使用mysql执行creation.sql,但它们似乎在运行过程中失败。一个CMD解决方案的例子,应该调用mysqld
(匹配mariadb Dockerfile中的内容),然后运行sql,但在运行容器时失败:
FROM mariadb:10.5.6
COPY /sql/* /sql/
CMD mysqld && mysql -e "source sql/creation.sql;" -uroot -p$MYSQL_ROOT_PASSWORD
带有shell脚本的CMD-不工作
一个基于脚本的解决方案的例子也失败了:
FROM mariadb:10.5.6
COPY /sql/* /sql/
COPY /scripts/* /scripts/
CMD ["./scripts/start.sh"]
start.sh:
exec mysqld
echo "Running start script\n" > start.log
for i in {1..20}
do
sleep 3
echo "Attempt $i"
echo "Attempt $i" &>> start.log
mysql -e "source sql/creation.sql;" -uroot -p$MYSQL_ROOT_PASSWORD &>> start.log
done
echo "Done" &>> start.log
是否有简单的解决方案?
有没有办法只使用Dockerfile运行SQL脚本文件,或者一个小的shell脚本?
3条答案
按热度按时间thtygnil1#
查看Docker Hub上的MariaDB文档,看起来有一个内置的进程用于执行辅助脚本:
当容器第一次启动时,将创建一个具有指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行扩展名为.sh,.sql,. sql.gz的文件。和.sql.xz文件。文件将按字母顺序执行。没有文件执行权限的.sh文件是源文件,而不是执行文件。您可以通过将SQL转储装载到该目录中来轻松填充mariadb服务,并提供具有贡献数据的自定义映像。SQL文件将默认导入到由MARIADB_DATABASE / MYSQL_DATABASE变量指定的数据库。
https://hub.docker.com/_/mariadb
wfveoks02#
您可以将命令添加为CMD行:
您也可以从docker-compose.yml文件调用CMD:
您可能需要在其中添加一行代码,使其休眠一段时间,以确保在脚本运行之前进程正常启动。您可以将其放在脚本中,但如果需要,可以将其作为脚本后面的第一个命令包含在CMD行中:
CMD first-command-to-sleep && second-command
.如果您发现CMD选项阻止MariaDB启动,您可能需要添加自己的请求以启动进程。查看他们的Dockerfile(https://github.com/MariaDB/mariadb-docker/blob/master/10.5/Dockerfile)建议如下:
所以你有
CMD first-command & second-command & mysqld
&
会让两个进程同时运行,而&&
会等待第一个进程成功完成后再运行:Can a bash script run simultaneous commands then wait for them to complete?这将作为shell进程执行,而不是exec,后者有一些缺点:https://til.codes/docker-run-vs-cmd-vs-entrypoint/
其他选项包括将所有内容放入shell脚本中,并在启动时调用它:
CMD ["start.sh"]
。在这里,您将确保最后一个命令mysqld作为exec mysqld
执行,然后确保它是执行的主进程,就像运行CMD ["mysqld"]
一样。如果你想创建自己的服务容器,可以使用像SupervisorD这样的服务:http://supervisord.org
或者为每个进程提供自己的容器。不使用标准的MariaDB容器,然后运行一个带有脚本的容器来调用命令或执行自定义进程。当然,这完全取决于您要做什么以及您需要与容器内容进行多少交互。如果调用Docker容器命令,您可以将Docker套接字挂载到您的容器中,安装docker,然后能够在其中执行
docker exec -it my_container_name mysql -e "source sql/creation.sql;" -uroot -pMyPasswordHere
命令:Access Docker socket within container。如果您需要构建一个在应用中执行大量自定义进程的超级容器,这可能是一个不错的选择。像往常一样,有很多方法可以做到这一点。我会从尝试开始:
如果mariadb没有启动,因为它覆盖了默认的CMD进程,那么可能会探索start.sh解决方案。
我不熟悉MariaDB,但我也会探索您尝试运行的命令是否可以作为配置文件传递或附加到start命令:
mysqld --variable --etc.
:https://hub.docker.com/_/mariadb/bksxznpy3#
我想添加其他几种在已经运行的容器中运行查询的方法
PS.我的例子是针对mariadb的,但它应该同样适用于mysql。