我正在尝试从mysql容器创建docker映像。问题是,新映像的数据库是干净的,但提交之前我在原始容器中手动创建的文件/文件夹会被复制。基本mysql镜像是官方的5.6docker是1.11。我检查了创建数据库时是否会出现/var/lib/mysql/d1文件夹,但新映像不会持久化该文件夹,尽管/root中的文件夹会持久化。
gojuced71#
这里发生了几件事:首先,docker commit是一种代码气味。它往往被那些用手动过程创建图像的人使用,而不是用Dockerfile自动构建,这样可以方便地重新创建。如果可能的话,我建议您转换到Dockerfile来创建图像。接下来,**docker commit将不会捕获对卷所做的更改。**如果尝试在Dockerfile中使用RUN步骤更新卷,也会出现同样的问题。这两种方法都捕获容器文件系统的更改,并将这些更改作为一个层存储在docker映像中,而卷不是容器文件系统中的一部分。如果对容器运行docker diff,这也是可见的。在这种情况下,上游映像已在其Dockerfile中定义了卷:
docker commit
RUN
docker diff
VOLUME /var/lib/mysql
docker没有从Dockerfile撤消创建的卷的命令。您需要从docker外部直接修改图像定义(不推荐),或者在删除该步骤的情况下构建自己的上游图像(推荐)。mysql映像提供的是在/docker-entrypoint-initdb.d中注入自己的数据库创建脚本的能力,您可以将其添加到扩展mysql的映像中,或者作为卷装入。这是您注入模式的地方,或者从已知的备份进行初始化以供开发。最后,如果目标是实现持久性,则应将数据存储在卷中,而不是通过提交容器:
/docker-entrypoint-initdb.d
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
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.通常,您应该使用卷来永久存储数据,并让容器是短暂的,而不将数据存储在容器本身。因此,我想许多人认为,不使用卷就试图持久化数据是一种糟糕的做法。
a docker commit will not capture changes made to a volume.
但在某些情况下,您可能会考虑将数据提交并冻结到图像中
例如,如果您在CI中使用图像进行自动测试,那么当您有一个包含所有表和记录的图像时,它会很方便。在github操作的情况下,您只需要拉动图像并创建数据库容器,然后对数据库运行测试。无需考虑数据迁移。
2条答案
按热度按时间gojuced71#
这里发生了几件事:
首先,
docker commit
是一种代码气味。它往往被那些用手动过程创建图像的人使用,而不是用Dockerfile自动构建,这样可以方便地重新创建。如果可能的话,我建议您转换到Dockerfile来创建图像。接下来,**
docker commit
将不会捕获对卷所做的更改。**如果尝试在Dockerfile中使用RUN
步骤更新卷,也会出现同样的问题。这两种方法都捕获容器文件系统的更改,并将这些更改作为一个层存储在docker映像中,而卷不是容器文件系统中的一部分。如果对容器运行docker diff
,这也是可见的。在这种情况下,上游映像已在其Dockerfile中定义了卷:docker没有从Dockerfile撤消创建的卷的命令。您需要从docker外部直接修改图像定义(不推荐),或者在删除该步骤的情况下构建自己的上游图像(推荐)。
mysql映像提供的是在
/docker-entrypoint-initdb.d
中注入自己的数据库创建脚本的能力,您可以将其添加到扩展mysql的映像中,或者作为卷装入。这是您注入模式的地方,或者从已知的备份进行初始化以供开发。最后,如果目标是实现持久性,则应将数据存储在卷中,而不是通过提交容器:
该卷允许您重新创建容器,在发布补丁(例如安全补丁)时升级到mysql的较新版本,而不会丢失数据。
要备份卷,将导出到tgz:
要恢复卷,这将从tgz创建一个:
w7t8yxp52#
您可以使用
docker commit
命令使数据持久化,如下所示。docker commit | Docker Documentation升
但正如BMitch的回答所说,
a docker commit will not capture changes made to a volume.
通常,您应该使用卷来永久存储数据,并让容器是短暂的,而不将数据存储在容器本身。
因此,我想许多人认为,不使用卷就试图持久化数据是一种糟糕的做法。
但在某些情况下,您可能会考虑将数据提交并冻结到图像中
例如,如果您在CI中使用图像进行自动测试,那么当您有一个包含所有表和记录的图像时,它会很方便。在github操作的情况下,您只需要拉动图像并创建数据库容器,然后对数据库运行测试。无需考虑数据迁移。