如何在Docker容器中用模式初始化MySQL数据库?

我正在尝试创build一个具有MySQL数据库的容器,并将模式添加到这些数据库。

我目前的Dockerfile是:

FROM mysql MAINTAINER (me) <email> # Copy the database schema to the /data directory COPY files/epcis_schema.sql /data/epcis_schema.sql # Change the working directory WORKDIR data CMD mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE < epcis_schema.sql 

为了创build容器,我遵循Docker上提供的文档并执行以下命令:

 docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} -e MYSQL_USER=${DB_USER} -e MYSQL_PASSWORD=${DB_USER_PASSWORD} -e MYSQL_DATABASE=${DB_NAME} -d mvpgomes/epcisdb 

但是当我执行这个命令的时候Container没有被创build,并且在Container的状态下可以看到CMD没有成功执行,实际上只有mysql命令被执行。

无论如何,有没有办法用模式初始化数据库,还是我需要手动执行这些操作?

对于这个超长的答案,我感到抱歉,但是,你有一个方法去find你想要的地方。 我会说通常你不会把数据库的存储放在与数据库本身相同的容器中,你要么挂载一个主机卷,以便数据在docker主机上保留,要么可能是一个容器可以用来保存数据(/ var / lib / mysql)。 此外,我是新来的MySQL,所以,这可能不是超高效。 那说…

我想这里可能有几个问题。 Dockerfile用于创build一个图像。 您需要执行构build步骤。 至less,从包含Dockerfile的目录中,您可以执行如下操作:

 docker build . 

Dockerfile描述了要创build的图像。 我不太了解mysql(我是一个postgres fanboy),但是,我在interwebs上search了'我如何初始化一个mysql docker container'。 首先,我创build了一个新的工作目录,我称之为mdir,然后创build了一个文件目录,我创build了一个epcis_schema.sql文件,创build一个数据库和一个表:

 create database test; use test; CREATE TABLE testtab ( id INTEGER AUTO_INCREMENT, name TEXT, PRIMARY KEY (id) ) COMMENT='this is my test table'; 

然后,我在文件目录中创build了一个名为init_db的脚本:

 #!/bin/bash # Initialize MySQL database. # ADD this file into the container via Dockerfile. # Assuming you specify a VOLUME ["/var/lib/mysql"] or `-v /var/lib/mysql` on the `docker run` command… # Once built, do eg `docker run your_image /path/to/docker-mysql-initialize.sh` # Again, make sure MySQL is persisting data outside the container for this to have any effect. set -e set -x mysql_install_db # Start the MySQL daemon in the background. /usr/sbin/mysqld & mysql_pid=$! until mysqladmin ping >/dev/null 2>&1; do echo -n "."; sleep 0.2 done # Permit root login without password from outside container. mysql -e "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION" # create the default database from the ADDed file. mysql < /tmp/epcis_schema.sql # Tell the MySQL daemon to shutdown. mysqladmin shutdown # Wait for the MySQL daemon to exit. wait $mysql_pid # create a tar file with the database as it currently exists tar czvf default_mysql.tar.gz /var/lib/mysql # the tarfile contains the initialized state of the database. # when the container is started, if the database is empty (/var/lib/mysql) # then it is unpacked from default_mysql.tar.gz from # the ENTRYPOINT /tmp/run_db script 

(这个脚本的大部分是从这里解除的: https : //gist.github.com/pda/9697520 )

这是我创build的files / run_db脚本:

 # start db set -e set -x # first, if the /var/lib/mysql directory is empty, unpack it from our predefined db [ "$(ls -A /var/lib/mysql)" ] && echo "Running with existing database in /var/lib/mysql" || ( echo 'Populate initial db'; tar xpzvf default_mysql.tar.gz ) /usr/sbin/mysqld 

最后,Dockerfile把它们全部绑定起来:

 FROM mysql MAINTAINER (me) <email> # Copy the database schema to the /data directory ADD files/run_db files/init_db files/epcis_schema.sql /tmp/ # init_db will create the default # database from epcis_schema.sql, then # stop mysqld, and finally copy the /var/lib/mysql directory # to default_mysql_db.tar.gz RUN /tmp/init_db # run_db starts mysqld, but first it checks # to see if the /var/lib/mysql directory is empty, if # it is it is seeded with default_mysql_db.tar.gz before # the mysql is fired up ENTRYPOINT "/tmp/run_db" 

所以,我cd到我的mdir目录(其中有Dockerfile与文件目录)。 然后我运行命令:

 docker build --no-cache . 

你应该看到这样的输出:

 Sending build context to Docker daemon 7.168 kB Sending build context to Docker daemon Step 0 : FROM mysql ---> 461d07d927e6 Step 1 : MAINTAINER (me) <email> ---> Running in 963e8de55299 ---> 2fd67c825c34 Removing intermediate container 963e8de55299 Step 2 : ADD files/run_db files/init_db files/epcis_schema.sql /tmp/ ---> 81871189374b Removing intermediate container 3221afd8695a Step 3 : RUN /tmp/init_db ---> Running in 8dbdf74b2a79 + mysql_install_db 2015-03-19 16:40:39 12 [Note] InnoDB: Using atomics to ref count buffer pool pages ... /var/lib/mysql/ib_logfile0 ---> 885ec2f1a7d5 Removing intermediate container 8dbdf74b2a79 Step 4 : ENTRYPOINT "/tmp/run_db" ---> Running in 717ed52ba665 ---> 7f6d5215fe8d Removing intermediate container 717ed52ba665 Successfully built 7f6d5215fe8d 

你现在有一个图像'7f6d5215fe8d'。 我可以运行这个图像:

 docker run -d 7f6d5215fe8d 

和图像开始,我看到一个实例string:

 4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3 

我可以“停止”它,然后重新启动它。

 docker stop 4b377 docker start 4b377 

如果您查看日志,第一行将包含:

 docker logs 4b377 Populate initial db var/lib/mysql/ ... 

然后,在日志的结尾处:

 Running with existing database in /var/lib/mysql 

这些是来自/ tmp / run_db脚本的消息,第一个表示数据库已从保存的(初始)版本解压缩,第二个表明数据库已经存在,因此使用了现有的副本。

这里是我上面描述的目录结构的ls -lR。 请注意,init_db和run_db是执行位设置的脚本:

 gregs-air:~ gfausak$ ls -Rl mdir total 8 -rw-r--r-- 1 gfausak wheel 534 Mar 19 11:13 Dockerfile drwxr-xr-x 5 gfausak staff 170 Mar 19 11:24 files mdir/files: total 24 -rw-r--r-- 1 gfausak staff 126 Mar 19 11:14 epcis_schema.sql -rwxr-xr-x 1 gfausak staff 1226 Mar 19 11:16 init_db -rwxr-xr-x 1 gfausak staff 284 Mar 19 11:23 run_db 

我有同样的问题,我想要初始化我的MySQL的Docker实例的架构,但我做了一些谷歌search和其他人的例子后,遇到了困难。 这是我如何解决它。

1)将您的MySQL模式转储到一个文件。

 mysqldump -h <your_mysql_host> -u <user_name> -p --no-data <schema_name> > schema.sql 

2)使用ADD命令将模式文件添加到Docker容器中的/docker-entrypoint-initdb.d目录中。 docker-entrypoint.sh文件将运行以".sql"结尾的目录中的任何文件。

Dockerfile:

 FROM mysql:5.7.15 MAINTAINER me ENV MYSQL_DATABASE=<schema_name> \ MYSQL_ROOT_PASSWORD=<password> ADD schema.sql /docker-entrypoint-initdb.d EXPOSE 3306 

3)启动Docker MySQL实例。

 docker-compose build docker-compose up 

感谢在Dockerfile中设置MySQL和导入转储,以便在docker-entrypoint.sh中提供线索,以及它同时运行SQL和shell脚本!

我已经尝试了格雷格的答案,成功的零,我必须做错了,因为我的数据库没有数据后,所有的步骤:我使用MariaDB的最新形象,以防万一。

然后,我决定阅读官方MariaDB图像的入口点,并用它来生成一个简单的docker-compose文件:

 database: image: mariadb ports: - 3306:3306 expose: - 3306 volumes: - ./docker/mariadb/data:/var/lib/mysql:rw - ./database/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" 

现在我可以坚持我的数据,并用我自己的模式生成一个数据库!

最简单的解决scheme是使用tutum / mysql

步骤1

 docker pull tutum/mysql:5.5 

第2步

 docker run -d -p 3306:3306 -v /tmp:/tmp -e STARTUP_SQL="/tmp/to_be_imported.mysql" tutum/mysql:5.5 

第三步:

获取高于CONTAINER_ID,然后执行命令docker logs查看生成的密码信息。

 docker logs #<CONTAINER_ID> 

2015年8月4日之后,如果您使用的是官方的mysql Docker镜像,您可以将文件添加/复制到/docker-entrypoint-initdb.d/目录中,并在容器初始化的情况下运行。 见github: https : //github.com/docker-library/mysql/commit/14f165596ea8808dfeb2131f092aabe61c967225如果你想在其他容器图像上实现它

另一种方式是基于以下这些合并的答复:

docker构成文件:

 version: "3" services: db: container_name: db image: mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=mysql - MYSQL_DATABASE=db volumes: - /home/user/db/mysql/data:/var/lib/mysql - /home/user/db/mysql/init:/docker-entrypoint-initdb.d/:ro 

/home/user ..是主机上的共享文件夹

而在/home/user/db/mysql/init文件夹中,只需删除一个包含以下内容的sql文件:

 CREATE DATABASE mydb; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%' IDENTIFIED BY 'mysql'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost' IDENTIFIED BY 'mysql'; USE mydb CREATE TABLE CONTACTS ( [ ... ] ); INSERT INTO CONTACTS VALUES ... [ ... ] 

根据官方的mysql文档 ,你可以在docker-entrypoint-initdb.d放入多个sql文件,它们按字母顺序执行

另一个简单的方法,使用docker – 组成下面的行:

 mysql: from: mysql:5.7 volumes: - ./database:/tmp/database command: mysqld --init-file="/tmp/database/install_db.sql" 

将数据库模式放入./database/install_db.sql。 每次当你build立你的容器,执行install_db.sql。

经过一番努力,使用命名卷(db-data)来看看Dockerfile。 重要的是在最后部分声明,我提到音量是[external]

所有这一切都很好!

 version: "3" services: database: image: mysql:5.7 container_name: mysql ports: - "3306:3306" volumes: - db-data:/docker-entrypoint-initdb.d environment: - MYSQL_DATABASE=sample - MYSQL_ROOT_PASSWORD=root volumes: db-data: external: true