如何在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