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

时间:2016-07-21 12:25:54

标签: mysql docker

我正在尝试在MySQL容器启动时创建多个数据库。 根据{{​​3}},我可以在图像的/docker-entrypoint-initdb.d中安装或复制我的脚本,它们将在启动时自动执行。

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

这是我的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

这是我的script.sql

CREATE DATABASE mydb;
CREATE DATABASE mydb2;

我构建并运行容器:

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

当我在tty中访问容器时,我可以看到script.sql位于/docker-entrypoint-initdb.d但未执行。

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

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

可能是什么问题?

10 个答案:

答案 0 :(得分:7)

在运行容器之前,请将data_volume设为空。并且你的sql文件肯定会被执行。

这里的问题:

在docker-entrypoint.sh中,使用/ var / lib / mysql中存在的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 

您可以在Dockerfile source

了解更多详情

答案 1 :(得分:5)

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

所以我要做的是制作一个简单的init.sh文件以删除datadir,然后启动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

当然,一旦我看到它按预期工作,就将-d添加到docker-compose

答案 2 :(得分:2)

简短说明
我有完全相同的问题,但是有一个mariadb图像(似乎与mysql的图像完全相同 docker-entrypoint.sh ),我想贡献到这个线程。希望如果我们很多人抱怨这个问题,我们可以修复它:)

运行 docker-compose.yml docker-entrypoint-initdb.d ”文件夹中包含的.sql脚本会被忽略 > 在我的生产环境(Linux),而完全相同的文件在我的开发环境(Windows 7)上完美无瑕。

这不允许我构建数据库结构(.sql文件包含所有CREATE TABLE语句......),因此它对我来说是一个主要的showstopper

详细说明
我尝试了以下解决方案:

  • 将.sql的EOL从CRLF更改为LF;
  • docker-entrypoint-initdb.d ”的各种chmod设置(以及包含的脚本);
  • 使用“docker exec”输入容器(可以按预期从容器中访问文件夹和脚本);
  • 将* .sh文件添加到“ docker-entrypoint-initdb.d ”(它将被完全忽略为.sql);

到目前为止没有成功。使用以下命令检查日志:

$ docker logs someappname_db >& logs_db.txt

显示来自docker-entrypoint.sh的以下代码块在Linux环境中根本不会被调用,正如@anteverse所说:

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

使用“docker exec”输入容器,我看到以下权限:

在Linux上:

root@deda78e393f9:/# ls -l
total 72
drwxr-xr-x    2 root root 4096 Mar 19 19:53 bin
drwxr-xr-x    2 root root 4096 Nov 19 16:32 boot
drwxr-xr-x    5 root root  340 Apr 29 15:53 dev
**drwxrwxrwx+   2 root root 4096 Apr 29 11:30 docker-entrypoint-initdb.d**
lrwxrwxrwx    1 root root   34 Mar 14 06:26 docker-entrypoint.sh -> usr/local/bin/docker-entrypoint.sh
...

在Windows 7上:

root@a3ff19060712:/# ls -l
total 64
drwxr-xr-x   2 root root  4096 Feb 17 09:07 bin
drwxr-xr-x   2 root root  4096 Nov 19 16:32 boot
drwxr-xr-x   5 root root   340 Apr 29 16:04 dev
**drwxrwxrwx   1 1000 staff    0 Apr 28 18:13 docker-entrypoint-initdb.d**
lrwxrwxrwx   1 root root    34 Feb 17 09:08 docker-entrypoint.sh -> usr/local/bin/docker-entrypoint.sh
...

它可能与UID有关:GID? 它们应该是1000:Linux上的员工吗?

我的Linux主机上的用户名为'admin',可能是一个不匹配的根(在容器上):admin(在主机上)东西?

<强>规格
开发环境:Windows 7,Docker 18.02.0-CE
生产环境:Linux的未指定风味(QNAP TS-253A),Docker 17.07.0-CE

[/share/Container/] # uname -or
4.2.8 GNU/Linux

[/share/Container/] # cat /etc/issue
Welcome to TS-253A, QNAP Systems, Inc.

[/share/Container/] # cat /etc/os-release
NAME="QTS"
VERSION="4.3.4 (20180215)"
ID=qts
PRETTY_NAME="QTS 4.3.4 (20180215)"
VERSION_ID="4.3.4"

<强>搬运工-compose.yml

version: '3'
services:

  db:
    container_name: someappname_db
    image: mariadb:latest
    restart: on-failure:3
    environment: 
      - MYSQL_DATABASE=someappname
      - MYSQL_ROOT_PASSWORD=someappname
      - MYSQL_USER=someappname
      - MYSQL_PASSWORD=someappname
      - MYSQL_ROOT_HOST=%
      - TZ=Europe/Stockholm
    ports:
      - 3306:3306  
    volumes:
      - dbdata:/var/lib/mysql      
      - /share/Container/someappname/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro
    networks:
      - net
    command: ["mysqld", "--user=mysql", "--lower_case_table_names=1"]

    # other services

volumes:
  dbdata:

networks:
  net:

<强>命令:
我总是在重新组装容器之前清理音量:

$ cd /share/Containers/someappname
$ docker stop $(docker ps -a -q --filter="name=someappname") && docker rm $(docker ps -a -q  --filter="name=someappname") && docker volume rm someappname_dbdata
$ docker-compose -f someappnameprod-docker-compose.yml up -d db

感谢您的帮助!

答案 3 :(得分:1)

你有没有解决这个问题?

一个简单的解决方法是在/docker-entrypoint-initdb.d /

中读取文件时使用绝对路径

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

进行了测试

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

然后是在/docker-entrypoint-initdb.d/中读取文件,但以下内容:

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

似乎找不到任何东西。

如果将其替换为:

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

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

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

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

CREATE DATABASE `test`;

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

答案 4 :(得分:0)

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

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

不要认为您的代码有任何问题,但谁知道。 我想你检查775是正确的所有者? 顺便说一下我使用FROM mysql:5

答案 5 :(得分:0)

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

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"]

答案 6 :(得分:0)

我对mariadb映像(版本:10.4)存在完全相同的问题,当我从头开始创建容器时,通过确保容器数据量不存在任何文件或目录来解决此问题。

这是我的docker compose文件:

  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

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

答案 7 :(得分:0)

我遇到了同样的问题,就像上面提到的@Ricky一样,根本原因是卷不为空。我运行命令>>> on_press("a") on_press: key: a myint: 0 >>> on_press("b") on_press: key: b myint: 1 >>> on_press("c") on_press: key: c myint: 2 >>> 来检查该卷是否仍然存在,然后再运行docker volume ls并确保有足够的卷。我使用docker-compose up删除了该卷,并运行docker-compose并确保运行在docker volume rm <volume name>中的脚本已经运行,并且我的数据已存储在数据库中。我会说不要担心chmod的东西(正如某些人所建议的那样),直到您在运行docker-compose之前确保卷不存在为止。如果这不起作用,您可以尝试使用文件权限。

这是我在工作容器中明智的选择,以防有人怀疑-

docker-entrypoint-initdb.d的权限

docker-entrypoint-initdb.d

以及以下有关sql脚本的信息-

drwxr-xr-x   1 root root 4.0K Nov 16 01:52 docker-entrypoint-initdb.d

答案 8 :(得分:0)

根据:https://stackoverflow.com/a/67435932/15926221

如果您在 mysql/mariadb 中使用“MYSQL_USER: root”作为 env 变量,这可能是问题的原因,因为已经预先创建了 root 用户。

答案 9 :(得分:-1)

这是我的docker文件完全正常的工作。 / sql-scripts /包含一个sql文件,该文件将在容器运行后执行。

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