MySQL scripts in docker-entrypoint-initdb are not

2020-02-10 02:42发布

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.

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.

This is my 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:

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.

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

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

What could be the problem?

标签: mysql docker
8条回答
看我几分像从前
2楼-- · 2020-02-10 02:46

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

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

docker-compose.yml:

volumes:
  - ./docker/mysql/scripts:/docker-entrypoint-initdb.d
  - ./mysql_data:/var/lib/mysql

init.sh:

#!/bin/bash
rm -rf mysql_data
docker-compose up --force-recreate

And of course add -d to docker-compose once I see it works as expected.

查看更多
对你真心纯属浪费
3楼-- · 2020-02-10 02:46

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.

This is my docker compose file:

  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

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.

查看更多
手持菜刀,她持情操
4楼-- · 2020-02-10 02:46

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

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

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

查看更多
成全新的幸福
5楼-- · 2020-02-10 02:50

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

Problems here:

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

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

    for f in /docker-entrypoint-initdb.d/*; do
        case "$f" in
            *.sh)     echo "$0: running $f"; . "$f" ;;
            *.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
            *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
            *)        echo "$0: ignoring $f" ;;
        esac
        echo
    done 

You can get more details at Dockerfile source

查看更多
虎瘦雄心在
6楼-- · 2020-02-10 02:58

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

FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/
查看更多
爱情/是我丢掉的垃圾
7楼-- · 2020-02-10 03:10

Have you solved the issue yet?

A simple workaround is to use absolute path when reading files in /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

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

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

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

doesn't seem to find anything.

If you replace it with:

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

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

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

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

CREATE DATABASE `test`;

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

查看更多
登录 后发表回答