bash - 如何针对 mariaDB docker 容器运行 sql 脚本
问题描述
我正在尝试在 docker 中创建一个 mariadb 实例,然后针对它运行目录中的所有文件。我知道我的脚本在我的 dockerfile 运行后执行时有效,但是当我将脚本放入 docker 文件时,它报告 mariadb 出现 127 错误。我尝试将调用 mysqld 放在脚本中,但这并没有解决问题。
Dockerfile
ENV MYSQL_ROOT_PASSWORD test
ENV MYSQL_DATABASE mydatabase
COPY . /usr/src
WORKDIR /usr/src
RUN script_runner.sh test
EXPOSE 3306
CMD ["mysqld"]
script_runner.sh
files=`ls start_script | grep ^'do'`
for script in $files
do
mysql -u root --password=$1 < `pwd`/start_script/$script
done
码头工人-compose.yml
...
mariadb:
build:
context: ./mariaDB
restart: always
ports:
- "3306:3306"
volumes:
- "/var/lib/mysql:/var/lib/mysql"
- "/srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld"
文件系统
-repo/
--docker-compose.yml
--mariadb/
---Dockerfile
---script_runner.sh
----start_script/
----do-release.sql
错误
Building mariadb
Step 1/8 : FROM mariadb:10.4.11-bionic
---> bc20d5f8d0fe
Step 2/8 : ENV MYSQL_ROOT_PASSWORD test
---> Running in 5987d662632b
Removing intermediate container 5987d662632b
---> e40256430e39
Step 3/8 : ENV MYSQL_DATABASE mydatabase
---> Running in a865ef21cdcc
Removing intermediate container a865ef21cdcc
---> dc5997996fef
Step 4/8 : COPY . /usr/src
---> 5314d67545bb
Step 5/8 : WORKDIR /usr/src
---> Running in 4643fe58e44e
Removing intermediate container 4643fe58e44e
---> 88e7901d501a
Step 6/8 : RUN script_runner.sh test
---> Running in 502ab4fddbb8
/bin/sh: 1: script_runner.sh: not found
ERROR: Service 'mariadb' failed to build: The command '/bin/sh -c script_runner.sh test' returned a non-zero code: 127
解决方案
我同意您需要使 script_runner.sh 脚本可执行的评论,这可能是 127 返回码的原因。但是我认为您会发现即使在使其可执行后它仍然无法工作。
在RUN script_runner.sh test
执行时,MySQL 服务器在构建过程中实际上还没有在 Docker 容器中运行。因此,如果您使脚本可执行,我想您会看到它会返回“无法连接到 mysql sock”类型错误。您必须启动 mysqld 作为 Docker 构建的一部分。另外,请记住,docker build 将自行执行每个 RUN 语句,并在该命令完成后对磁盘进行一层更改。如果您只是尝试发出一个RUN mysqld
(或类似的),则 mysqld 进程将启动并永远阻塞(假设它不守护进程)或(如果您告诉它守护进程)它将启动并且一旦它移动到后台,docker会做一层磁盘然后执行你的script_runner.sh
,但是mysql已经退出了。
如果你想这样做,你有两个选择:
- 将两者组合成一个 RUN 语句,例如
RUN mysqld_safe && script_runner.sh
- 让您的 script_runner.sh 在尝试执行 mysql 客户端之前启动 mysqld。
无论哪种方式都应该有效,并且(我认为)最终会得到相同的单层磁盘更改。这些文档在他们的最佳实践建议中涉及到这一点(尽管出于性能原因,他们在这里试图最小化层数):
推荐阅读
- python - 用于在 Selenium 中读取与切换开关相关的文本标签的 Python 代码
- javascript - 我可以在 JavaScript 中使用 System.Drawing.Color 吗?
- java - 在 Spring 应用程序中使用 JPA 连接多个表时从数据库获取最近更新的结果
- apache-kafka - Kafka 处理器 API,每条处理的记录只有一次语义
- android - 构建一个签名的 Apk
- ios - 使用 pushViewController 时出现“致命错误:在展开可选值时意外发现 nil”
- php - PHP urlencode 返回意外结果
- python - Conda 列表未在虚拟环境中显示包
- javascript - 尝试使用 await 测试使用 mocha 和 chai 获取
- c++ - Clang 和 GCC 中什么级别的优化消除了 noexcept 代码周围的 try-catch?