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
MySQL scripts in docker-entrypoint-initdb are not executed
提问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.d
of 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.sh
doesn't see files in the /docker-entrypoint-initdb.d
directory.
但是我的脚本根本没有执行。似乎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.sql
is in the /docker-entrypoint-initdb.d
but is not executed.
当我在TTY访问容器我可以看到script.sql
在/docker-entrypoint-initdb.d
,但不执行。
I have seen the docker logs -f somedb
output but there is no error.
我已经看到了docker logs -f somedb
输出,但没有错误。
I have tried with .sh
file, 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 -d
to docker-compose
once I see it works as expected.
当然-d
,docker-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