MySQL Docker 容器未将数据保存到新映像

2022-01-24 00:00:00 docker database save mysql

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

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.

这是我用来构建初始映像的 Dockerfile (myorg/mysql:base).

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

并运行 MySQL 以导入架构:

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

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

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

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

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

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

然后进入新图片:

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

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

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.

我想知道这是否与可信映像 Dockerfile 具有 VOLUME ["/etc/mysql", "/var/lib/mysql"] 的事实有关,因此它会挂载数据库目录作为卷.我的 Dockerfile 没有这个命令,但我不知道它是否被继承(我真的不明白卷如何工作得足够好,不知道这可能如何影响我的构建).我不需要将 db 作为卷安装,因为我需要另一个容器通过网络连接来连接它(我将为此使用 docker 链接).

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,我在 OS X 10.9.5 上运行 boot2docker 1.3.2.

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

推荐答案

作为另一个答案,您已经声明无法提交卷,并且子容器实际上确实从父容器继承了卷定义.因此,对卷的任何更改都将被丢弃.我想添加诸如 mysql 数据库文件之类的数据,出于多种原因,您不应该尝试将其提交到您的映像中.

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. 如果您必须迁移容器,那么如果容器中的数据不在卷中,则没有简单的方法可以从容器中提取数据.
  2. 如果您想启动多个共享数据的容器,您必须将数据保存在一个卷中.
  3. 如果您想使用新的卷或端口更改容器定义,您必须删除并重新创建它.如果容器中有数据,您将丢失它.(请参阅这个问题的示例这种情况.)
  4. 联合文件系统比普通文件系统慢,这会降低您的应用程序或数据库的速度.

那么你应该怎么做呢?

  1. 使用可与服务容器的任何实例链接的仅数据容器.然后,您可以使用 volumes-from 将数据放入服务容器中.
  2. 使用主机挂载的卷,以便您可以重新启动容器并将相同的位置挂载到新容器中.

相关文章