docker提交mysql不保存

ohfgkhjo  于 2022-10-22  发布在  Docker
关注(0)|答案(2)|浏览(206)

我正在尝试从mysql容器创建docker映像。问题是,新映像的数据库是干净的,但提交之前我在原始容器中手动创建的文件/文件夹会被复制。
基本mysql镜像是官方的5.6
docker是1.11。
我检查了创建数据库时是否会出现/var/lib/mysql/d1文件夹,但新映像不会持久化该文件夹,尽管/root中的文件夹会持久化。

gojuced7

gojuced71#

这里发生了几件事:
首先,docker commit是一种代码气味。它往往被那些用手动过程创建图像的人使用,而不是用Dockerfile自动构建,这样可以方便地重新创建。如果可能的话,我建议您转换到Dockerfile来创建图像。
接下来,**docker commit将不会捕获对卷所做的更改。**如果尝试在Dockerfile中使用RUN步骤更新卷,也会出现同样的问题。这两种方法都捕获容器文件系统的更改,并将这些更改作为一个层存储在docker映像中,而卷不是容器文件系统中的一部分。如果对容器运行docker diff,这也是可见的。在这种情况下,上游映像已在其Dockerfile中定义了卷:

VOLUME /var/lib/mysql

docker没有从Dockerfile撤消创建的卷的命令。您需要从docker外部直接修改图像定义(不推荐),或者在删除该步骤的情况下构建自己的上游图像(推荐)。
mysql映像提供的是在/docker-entrypoint-initdb.d中注入自己的数据库创建脚本的能力,您可以将其添加到扩展mysql的映像中,或者作为卷装入。这是您注入模式的地方,或者从已知的备份进行初始化以供开发。
最后,如果目标是实现持久性,则应将数据存储在卷中,而不是通过提交容器:

docker run -v mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql

该卷允许您重新创建容器,在发布补丁(例如安全补丁)时升级到mysql的较新版本,而不会丢失数据。
要备份卷,将导出到tgz:

docker run --rm -v mysql-data:/source busybox tar -cC /source . >backup.tgz

要恢复卷,这将从tgz创建一个:

docker run --rm -i -v mysql-data:/target busybox tar -xC /target <backup.tgz
w7t8yxp5

w7t8yxp52#

您可以使用docker commit命令使数据持久化,如下所示。

docker commit CONTAINER_ID REPOSITORY:TAG

docker commit | Docker Documentation
但正如BMitch的回答所说,a docker commit will not capture changes made to a volume.
通常,您应该使用卷来永久存储数据,并让容器是短暂的,而不将数据存储在容器本身。
因此,我想许多人认为,不使用卷就试图持久化数据是一种糟糕的做法。

但在某些情况下,您可能会考虑将数据提交并冻结到图像中

例如,如果您在CI中使用图像进行自动测试,那么当您有一个包含所有表和记录的图像时,它会很方便。在github操作的情况下,您只需要拉动图像并创建数据库容器,然后对数据库运行测试。无需考虑数据迁移。

相关问题