首页 > 解决方案 > 如何针对 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

标签: bashdockerdocker-composemariadb

解决方案


我同意您需要使 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已经退出了。

如果你想这样做,你有两个选择:

  1. 将两者组合成一个 RUN 语句,例如RUN mysqld_safe && script_runner.sh
  2. 让您的 script_runner.sh 在尝试执行 mysql 客户端之前启动 mysqld。

无论哪种方式都应该有效,并且(我认为)最终会得到相同的单层磁盘更改。这些文档在他们的最佳实践建议中涉及到这一点(尽管出于性能原因,他们在这里试图最小化层数):

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers


推荐阅读