docker-entrypoint-initdb 中的 MySQL 脚本不执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38504257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 21:56:33  来源:igfitidea点击:

MySQL scripts in docker-entrypoint-initdb are not executed

mysqldocker

提问by Canis Majoris

I am trying to create multiple databases when a MySQL container starts up. According to https://github.com/docker-library/mysql/pull/18, I can mount or copy my scripts in the /docker-entrypoint-initdb.dof the image and they will be executed automatically on start up.

我正在尝试在 MySQL 容器启动时创建多个数据库。根据https://github.com/docker-library/mysql/pull/18,我可以/docker-entrypoint-initdb.d在镜像中挂载或复制我的脚本,它们将在启动时自动执行。

However my scripts are not at all executed. Seems like the docker-entrypoint.shdoesn't see files in the /docker-entrypoint-initdb.ddirectory.

但是我的脚本根本没有执行。似乎docker-entrypoint.sh没有看到目录中的/docker-entrypoint-initdb.d文件。

This is my Dockerfile:

这是我的 Dockerfile:

FROM mysql
ADD script.sql /docker-entrypoint-initdb.d/script.sql
RUN chmod -R 775 /docker-entrypoint-initdb.d

ENV MYSQL_ROOT_PASSWORD mypass

This is my script.sql:

这是我的script.sql

CREATE DATABASE mydb;
CREATE DATABASE mydb2;

I build and run the container:

我构建并运行容器:

$ docker build -t mysql .
$ docker run -v data_volume:/var/lib/mysql --name somedb -d mysql

When I access the container in tty I can see that the script.sqlis in the /docker-entrypoint-initdb.dbut is not executed.

当我在TTY访问容器我可以看到script.sql/docker-entrypoint-initdb.d,但不执行。

I have seen the docker logs -f somedboutput but there is no error.

我已经看到了docker logs -f somedb输出,但没有错误。

I have tried with .shfile, I also have tried with Maria-db, the result is the same.

我试过.sh文件,我也试过 Maria-db,结果是一样的。

What could be the problem?

可能是什么问题呢?

采纳答案by Ricky

Please make data_volume empty before run your container. And your sql files will be executed for sure.

请在运行容器之前将 data_volume 清空。你的 sql 文件肯定会被执行。

Problems here:

这里的问题:

In docker-entrypoint.sh, the check the first running by using exist of mysql directory in /var/lib/mysql

在docker-entrypoint.sh中,使用/var/lib/mysql中mysql目录的exists检查第一次运行

if [ ! -d "$DATADIR/mysql" ]; then
    //Some other logic here

    for f in /docker-entrypoint-initdb.d/*; do
        case "$f" in
            *.sh)     echo "
volumes:
  - ./docker/mysql/scripts:/docker-entrypoint-initdb.d
  - ./mysql_data:/var/lib/mysql
: running $f"; . "$f" ;; *.sql) echo "
#!/bin/bash
rm -rf mysql_data
docker-compose up --force-recreate
: running $f"; "${mysql[@]}" < "$f"; echo ;; *.sql.gz) echo "
FROM mysql:5.7.17
ADD scripts/init.sql /docker-entrypoint-initdb.d/

RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/

CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;; *) echo "
  mariadb:
    image: mariadb:10.4
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ********
    volumes:
    - ./storage/db:/var/lib/mysql:rw
    - ./app/db/SQL:/docker-entrypoint-initdb.d/:rw
    ports:
    - 3306:3306/tcp
: ignoring $f" ;; esac echo done

You can get more details at Dockerfile source

您可以在Dockerfile 源中获得更多详细信息

回答by Kim Lundberg Stegenborg Madsen

So I had the same issue for hours, and then decided to look into docker-entrypoint.sh. It turns out that the script checks for $DATADIR/mysql, typical /var/lib/mysql and skips the rest of the code if the datadir exists, incl. docker-entrypoint-initdb.d

所以我几个小时都遇到了同样的问题,然后决定研究 docker-entrypoint.sh。事实证明,脚本会检查 $DATADIR/mysql、典型的 /var/lib/mysql 并在 datadir 存在时跳过其余代码,包括。docker-entrypoint-initdb.d

So what I did was make a simple init.sh file to remove the datadir then start docker.

所以我所做的是制作一个简单的 init.sh 文件来删除 datadir 然后启动 docker。

docker-compose.yml:

docker-compose.yml:

FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/

init.sh:

初始化.sh:

for f in /docker-entrypoint-initdb.d/*; do

And of course add -dto docker-composeonce I see it works as expected.

当然-ddocker-compose一旦我看到它按预期工作,就添加。

回答by user1291806

I had the same problem. I solved it by changing directory owner before starting entrypoint script. Example Dockerfile:

我有同样的问题。我通过在启动入口点脚本之前更改目录所有者来解决它。示例 Dockerfile:

for f in /usr/local/bin/docker-entrypoint-initdb.d/*; do

回答by eldadfux

I had the exact same issue with the mariadb image (version: 10.4) and I solved it by making sure my container data volume is empty from any files or directories when I create the container from scratch.

我在 mariadb 映像(版本:10.4)上遇到了完全相同的问题,当我从头开始创建容器时,我通过确保我的容器数据卷从任何文件或目录中为空来解决它。

This is my docker compose file:

这是我的 docker compose 文件:

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

COPY docker-entrypoint-initdb.d/ /usr/local/bin/docker-entrypoint-initdb.d/
RUN chmod -R +x /usr/local/bin/docker-entrypoint-initdb.d

For me I just had to make sure this path: './storage/db' is empty from files. Please notice that the directory has to exists but be empty.

对我来说,我只需要确保这个路径:'./storage/db' 从文件中是空的。请注意,该目录必须存在但为空。

回答by Rohit Salecha

Here is my docker file working absolutely fine. /sql-scripts/ contains a sql file which is executed once the container runs.

这是我的 docker 文件工作正常。/sql-scripts/ 包含一个 sql 文件,一旦容器运行,就会执行该文件。

CREATE DATABASE `test`;

回答by anteverse

Have you solved the issue yet?

你解决问题了吗?

A simple workaround is to use absolute path when reading files in /docker-entrypoint-initdb.d/

一个简单的解决方法是在读取 /docker-entrypoint-initdb.d/ 中的文件时使用绝对路径

I made my test using the default config of: https://github.com/docker-library/mysql/blob/master/5.7/Dockerfile#L70

我使用默认配置进行了测试:https: //github.com/docker-library/mysql/blob/master/5.7/Dockerfile#L70

The docker-entrypoint.sh is first moved to /usr/local/bin before execution.

docker-entrypoint.sh 在执行前首先移动到 /usr/local/bin。

Then it comes to reading files in /docker-entrypoint-initdb.d/, but the following:

然后是读取/docker-entrypoint-initdb.d/中的文件,但如下:

RUN mkdir -p /docker-entrypoint-initdb.d && mv myScript.sql /docker-entrypoint-initdb.d/myScript.sql

doesn't seem to find anything.

似乎没有找到任何东西。

If you replace it with:

如果您将其替换为:

##代码##

and then make sure the folder is populated by the Dockerfile command:

然后确保该文件夹由 Dockerfile 命令填充:

##代码##

From there, build a test statement in /docker-entrypoint-initdb.d/test.sql

从那里,在 /docker-entrypoint-initdb.d/test.sql 中构建一个测试语句

##代码##

Finally build and run the image and you should see your database created.

最后构建并运行映像,您应该会看到创建的数据库。

回答by Zeromus

not really an answer to that behavior but i usually do it like this:

不是对这种行为的真正答案,但我通常这样做:

##代码##

don't think there's anything wrong with your code but who knows. i suppose you checked 775 is the correct owner? btw im using FROM mysql:5

不要认为你的代码有什么问题,但谁知道呢。我想你检查过 775 是正确的主人吗?顺便说一句,我正在使用 FROM mysql:5