Docker Compose MySQL 导入 .sql 文件

50

我在使用docker-compose导入.sql备份文件时遇到了问题。我按照文档指示做,将.sql文件放在docker-entrypoint-initdb.d目录下,然后运行docker-compose up命令,但是.sql文件没有被复制到容器内。

我尝试使用-vf标志停止容器,但也无法解决问题。我在我的.yml脚本中出错了吗?

我在根目录下的database/db-dump/目录中有dump.sql文件。

frontend:
  image: myimage
  ports:
   - "80:80"
  links:
   - mysql
mysql:
  image: mysql
  ports:
   - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: rootpass
    MYSQL_USER: dbuser
    MYSQL_PASSWORD: userpass
    MYSQL_DATABASE: myimage_db
  volumes:
   - ./database/db-dump:/docker-entrypoint-initdb.d

1
你的docker-compose在我的机器上运行正常。请附上您转储位置的目录结构和您如何检查哪个文件已复制到容器中。 - Cortwave
目录结构为“database> db-dump> dump.sql”,一旦组合启动,连接到mysql容器并检查始终为空的docker-entrypoint-initdb.d目录。 - GafferG
7个回答

75

这对我管用了,

version: '3.1'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    volumes:
      - ./mysql-dump:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: ecommerce

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

mysql-dump必须是一个目录。目录中的所有.sql文件将被导入。


2
请记住,您的SQL语句可能需要CREATE DATABASE [name]USE [name]语句。您可以通过使用docker exec -i [container_id] sh -c 'exec mysql -uroot -p"[password]"' < /path/to/db/files/dump.sql来确认您的SQL文件是否有效。如果在此处有效,则应该在您的docker-compose文件中也有效。 - farinspace
如果db容器已经构建好了,docker compose up可能不会反映入口点的添加。首先执行docker compose down来删除所有容器 - undefined

45

经过多次尝试调整音量设置,我找到了一个解决方法。

我在 Dockerfile 中创建了另一张基于 mysql 的镜像,并添加了以下内容。

FROM mysql:5.6

ADD dump.sql /docker-entrypoint-initdb.d

然后从组成中删除卷并运行新映像。

frontend:
  image: myimage
  ports:
   - "80:80"
  links:
   - mysql
mysql:
  image: mymysql
  ports:
   - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: rootpass
    MYSQL_USER: dbuser
    MYSQL_PASSWORD: userpass
    MYSQL_DATABASE: myimage_db

这种方式可以始终复制转储并在启动时运行


2
你应该看一下:https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb - creekorful
1
等等,没有必要为了导入一些文件而构建一个新的镜像:只有在数据永远不会改变,并且您要与同事共享镜像,以便他们不需要每次都导入文件时才有意义。但对于正常情况,使用卷是应该采用的解决方案。 - funder7

25

这段内容出现在Docker MySQL镜像的文档页面上:https://hub.docker.com/_/mysql/

初始化一个新的实例

当容器首次启动时,将创建一个指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行在 /docker-entrypoint-initdb.d 中找到的扩展名为 .sh.sql.sql.gz 的文件。文件将按字母顺序执行。您可以通过将SQL转储文件挂载到该目录中轻松地填充您的mysql服务,并提供自定义镜像以提供贡献的数据。默认情况下,SQL文件将被导入到由MYSQL_DATABASE变量指定的数据库中。


3
在容器创建时才会读取/docker-entrypoint-initdb.d目录。当OP运行docker-compose up时,他要求进行数据库“更新”。 - creekorful

20

MySQL数据库转储文件schema.sql位于/mysql-dump/schema.sql目录中,并且在初始化过程中创建表。

docker-compose.yml:

mysql:
    image: mysql:5.7
    command: mysqld --user=root
    volumes:
      - ./mysql-dump:/docker-entrypoint-initdb.d
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

4

我在mysql方面遇到了类似的问题,我通过docker-compose将本地目录挂载到/docker-entrypoint-initdb.d卷中的/configs/mysql/data,并包含一个mydatabasedump.sql文件。虽然文件被加载到容器中,但在容器初始化时并没有执行或填充数据库。我的初始docker-compose.yml如下:

#docker-compose.yml
version: '3'
services:
    db:
        build: ./build/mysql/ #this is pointing to my Dockerfile
        container_name: MYSQL_Database
        restart: always
        environment:
        MYSQL_PORT: 3306
        MYSQL_ROOT_PASSWORD: admin
        MYSQL_DATABASE: my_app_database
        MYSQL_USER: admin
        MYSQL_PASSWORD: admin
    volumes:
        - ./configs/mysql/data:/docker-entrypoint-initdb.d:

我发现了两个解决这个问题的方法:
第一个方法是,在我登录正在运行的容器后,确认 mydatabasedump.sq 文件在容器的 docker-entrypoint-initdb.d 目录中存在并且可执行;然后我在本地 /configs/mysql/data 目录下创建并添加了一个名为 dump.sh 的 bash 脚本,该脚本在容器初始化后执行,它包含一个单一的 mysql 命令,将 my_database_dump.sql 复制到 my_app_database 中。bash 脚本看起来像这样:
    #!/bin/bash
    #dump.sh
    mysql -uadmin -padmin my_app_database < my_database_dump.sql 
    #end of dump.sh

我通过 Dockerfile 中的 ENTRYPOINT 指令执行了这个脚本,像这样:

    #Dockerfile
    FROM mysql:5.5
    ENTRYPOINT [ "dump.sh" ]
    EXPOSE 80
    #end of Dockerfile

在意识到初始问题是由于容器构建后挂载的卷没有初始化数据库,因此无法在启动时使用转储文件(或执行该目录中的任何脚本)之后,第二个解决方案是将我的compose-file中的volumes指令移到构建指令之前。这起作用了,使我能够删除dump.sh脚本和Dockerfile中的DOCKERENTRY指令。修改后的docker-compose.yml如下:

#docker-compose.yml
version: '3'
services:
    db:
        volumes:
          - ./configs/mysql/data:/docker-entrypoint-initdb.d
       build: ./build/mysql/ #this is pointing to my Dockerfile
         container_name: MYSQL_Database
         restart: always
     environment:
         MYSQL_PORT: 3306
         MYSQL_ROOT_PASSWORD: admin
         MYSQL_DATABASE: my_app_database
         MYSQL_USER: admin
         MYSQL_PASSWORD: admin

谢谢!这对我的情况有所帮助,而其他人则没有。 - PepperAddict

3

我想保留容器的原始设置,所以我尝试在已经运行的容器上进行还原。这似乎起作用了:

cat dump.sql | docker-compose exec -T db mysql -h localhost -u root -psomewordpress -v

但是非常慢,且冗长的输出似乎被缓存,因此我尝试了:

docker-compose cp dump.sql db:/tmp/
docker-compose exec db sh -c "mysql -h localhost -u root -psomewordpress -v < /tmp/dump.sql"

至少提供了更快的反馈。

对某些人可能有用?看起来主要是因为我在转储时使用了--skip-extended-insert,没有扩展插入语句会更快。


2

我也有这个问题。我通过docker-compose将一个包含init.sql文件的本地目录./mysql-dump挂载到docker-entrypoint-initdb.d卷上,文件会被加载到容器中,但在容器初始化时不会执行或填充数据库。我的初始docker-compose.yml如下:

mysqld:
    image: mysql
    container_name: mysqld
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/my.cnf
      - ./init:/docker-entrypoint-initdb.d
    env_file: .env
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=fendou
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 
             --default-authentication-plugin=mysql_native_password

但是对我来说它不起作用。我找到了另一个解决这个问题的方法:将--init-file /data/application/init.sql添加到mysql命令中,更改上面的配置如下:
mysqld:
    image: mysql
    container_name: mysqld
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/my.cnf
      # - ./init:/docker-entrypoint-initdb.d
    env_file: .env
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=fendou
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 
             --default-authentication-plugin=mysql_native_password
             --init-file /docker-entrypoint-initdb.d/init.sql  #attention here

希望它对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接