MySQL Docker容器不会将数据保存到新映像 [英] MySQL Docker container is not saving data to new image

查看:361
本文介绍了MySQL Docker容器不会将数据保存到新映像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个预设有特定模式和种子数据的MySQL Docker容器,以便我可以将其他容器作为数据库连接到它。我正在使用信任的dockerfile / mysql图片作为基础,而我写了一个Docker文件,从该基础创建一个新的图像,并将我的schema.sql添加到它。在构建该映像(mysql:base)之后,我一直在尝试在新的容器中运行bash,然后进入mysql并创建我的数据库,然后导入模式。然后我退出容器,并尝试将容器提交到一个新的Docker映像。但是,生成的映像不会保留对MySQL数据库的任何更改。它确实存在我在容器中写入的其他文件,而不是数据库。



这里是用于构建初始映像的Dockerfile(myorg / mysql:base) 。



$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ sql /data/schema.sql

EXPOSE 3306

#定义工作目录。
WORKDIR / data

CMD [mysqld_safe]

建立后,我进入图像:

  docker run -i -t myorg / mysql:base bash 

并运行MySQL导入架构:

  myslqd_safe& 
141218 00:15:56 mysqld_safe从/ var / lib / mysql启动mysqld守护进程数据库

mysql -u root

mysql> CREATE DATABASE mydb;
退出;

mysql -u root -D mydb< schema.sql

我可以进入mysql并验证模式是否已成功导入:

  mysql -u root -D mydb -eselect * from tokens; 

另外,如果我进入 / var / lib / mysql 我可以看到有一个 mydb 目录包含与db相对应的.frm文件。



但是当我退出并尝试将该容器提交到一个新的映像时:

  docker commit -m =import schema.sql -a =我72c2ff39dd65 myorg / mysql:seed 

然后进入新的图像:

  docker run -i -t --rm myorg / mysql:seed bash 

db文件不再在/ var / lib / mysql中,并运行 mysql -u root -eSHOW DATABASES 不显示 mydb 数据库,只有默认的 mysql information_schema performance_schema dbs。我发现如果我在容器中创建了一个新的文本文件( echo'test'> newfile ),该文件将出现在提交的图像中,而不是数据库。



我想知道这是否与可信图像Dockerfile具有 VOLUME [/ etc / mysql,/ var / lib / mysql] ,所以它将db目录作为一个卷进行安装。我的Dockerfile没有这个命令,但是我不知道是否继承了这个命令(我真的不明白卷如何运行得很好,知道这可能会影响我的构建)。我不需要将数据库挂载为一个卷,因为我需要另一个容器通过网络连接连接(我将使用docker链接)。



FWIW,我在OS X 10.9.5上运行boot2docker 1.3.2。

解决方案

作为另一个答案,你已经说卷不能被提交,并且子容器确实从父节点继承卷定义。因此,对卷的任何更改都将被丢弃。我想添加数据,如mysql数据库文件应该总是在卷的几个原因,你不应该尝试提交到您的图像。


  1. 如果您不得不迁移容器,则不容易从容器中提取数据,如果它不在卷中。

  2. 如果要启动共享数据的多个容器,您必须在卷中具有数据。

  3. 如果要使用新卷或端口更改容器定义你必须删除并重新创建它。如果您在容器中有数据,您将会松动它。 (请参阅此问题,以获取这种情况。)

  4. 联合文件系统比正常的文件系统慢,这会减慢你的应用程序或数据库。

那么你该怎么办?


  1. 使用可以与任何实例服务容器然后,您可以使用卷从您的数据到服务容器。

  2. 使用主机挂载的卷,以便您可以重新启动容器并将相同的位置安装到新的容器中。 >


I'm trying to create a MySQL Docker container that is preset with a certain schema and seed data so that I can have other containers connect to it as a db. I'm using the trusted dockerfile/mysql image as a base, and I wrote a Dockerfile to create a new image from that base and add my schema.sql into it. After building that image (mysql:base), I've been trying to run bash in new container, then go into mysql and create my database and then import the schema. I then exit the container and try to commit the container to a new Docker image. However, the resulting image does not persist any of the changes I made to the MySQL db. It does persist other files that I wrote in the container, but not the db.

Here is the Dockerfile I use to build the initial image (myorg/mysql:base).

FROM dockerfile/mysql:latest
MAINTAINER (me)

ADD schema.sql /data/schema.sql

EXPOSE 3306

# Define working directory.
WORKDIR /data

CMD ["mysqld_safe"]

After building that, I go into the image:

docker run -i -t myorg/mysql:base bash

And run MySQL to import the schema:

myslqd_safe &
141218 00:15:56 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql

mysql -u root

mysql> CREATE DATABASE mydb;
exit;

mysql -u root -D mydb < schema.sql

I can go into mysql and verify the schema has been imported successfully:

 mysql -u root -D mydb -e "SELECT * from tokens;"

Also, if I go into /var/lib/mysql I can see that there is a mydb directory that contains .frm files corresponding to the db.

But when I exit and try to commit that container to a new image:

docker commit -m="import schema.sql" -a="Me" 72c2ff39dd65 myorg/mysql:seed

And then go into the new image:

docker run -i -t --rm myorg/mysql:seed bash

The db files are no longer in /var/lib/mysql, and running mysql -u root -e "SHOW DATABASES" does not show the mydb database, only the default mysql, information_schema, and performance_schema dbs. I found that if I created a new textfile in the container (echo 'test' > newfile), that file would be present in the committed image, but not the db.

I wonder if this has something to do with the fact that the trusted image Dockerfile has VOLUME ["/etc/mysql", "/var/lib/mysql"] so it mounts the db directory as a volume. My Dockerfile does not have this command, but I don't know if it's inherited anyway (I don't really understand how volumes work well enough to know how this might affect my build). I don't need the db mounted as a volume because I need another container to connect to it over a network connection (I'm going to use docker links for that).

FWIW, I am running boot2docker 1.3.2 on OS X 10.9.5.

解决方案

As another answer and you have stated volumes cannot be committed and child containers do in fact inherit volume definitions from parents. Hence any changes to the volume will be discarded. I would like to add data such as mysql database files should always be in volumes for several reasons and you should not be trying to commit it into your image.

  1. If you have to migrate containers there is no easy way to extract data from containers if its not in a volume.
  2. If you want to start multiple containers that share data you have to have data in a volume.
  3. If you want to change your container definition with say new volumes or ports you have to delete and recreate it. If you have data in the container you will loose it. (See this question for an example of this case.)
  4. The union file system is slower than normal file systems which will slow down your application or database.

So what should you do instead?

  1. Use a data only container that can be linked with any instance of the service container. Then you can use volumes-from to get your data into the service container.
  2. Use a host mounted volume so that you can restart containers and mount the same location into new containers.

这篇关于MySQL Docker容器不会将数据保存到新映像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆