在Docker中持久化MySQL数据

37次阅读
没有评论

问题描述

在使用Docker构建过程中,遇到了一个问题:在两个不同的docker build语句中启动MySQL服务器(使用官方MySQL Docker镜像派生),数据库文件是否会保留?尽管他认为会,但实际情况似乎并非如此。他在日志中看到了相关信息,但仍然对问题的原因感到困惑。

解决方案

请注意以下操作可能涉及版本差异及潜在风险,请在操作前进行备份。

数据在Docker镜像层间的保存

问题的根本在于Docker镜像的构建和容器的运行是分开进行的。每个Docker镜像层都会生成一个临时容器,在这个容器中执行RUN等指令,然后将容器的状态保存为镜像的一层。但是,由于容器之间的层是隔离的,文件系统的更改不会在层之间传播。

使用数据卷进行持久化

为了在更新的容器之间保留数据,您需要使用数据卷来将数据映射到主机上的目录,而不是使用容器特定的挂载点。以下是一种解决方案,您可以使用-v选项来创建一个数据卷,将MySQL数据映射到主机上的一个目录:

docker run -d -v /var/container_data/mysql:/var/lib/mysql mysql_image

上面的命令中,-d表示以后台模式运行容器,-v用于创建数据卷映射。其中/var/container_data/mysql是主机上的目录,/var/lib/mysql是容器内MySQL数据的目录。通过这种方式,您可以确保数据在容器更新时得以保留。

要在docker-compose.yml中使用数据卷,可以这样定义:

version: '3'
services:
  mysql:
    image: mysql
    volumes:
      - /var/container_data/mysql:/var/lib/mysql

注意:在生产环境中,通常不会将应用程序数据存储在容器中,因为容器应该是可变性的。但是在演示和测试环境中,使用数据卷可能会很有用。

解答用户疑问

用户还提到了一个问题:为什么使用apt-get install ..安装的软件包会在最终镜像中保留下来,而数据库文件不会?这是因为RUN apt-get install ..会创建一个临时容器,执行命令,然后将容器的状态保存为镜像的一层。但在您的示例中,第一个RUN语句是在创建数据并提交到最终镜像中,然后在第二个RUN语句中使用新的临时容器启动了一个新的MySQL服务器,由于容器是隔离的,这个服务器并不包含第一个服务器的数据。

希望以上解决方案能够帮助您理解在Docker中如何持久化MySQL数据以及为何在不同容器之间的数据不会保留。如果您想深入了解Docker容器和数据卷的工作原理,可以查阅相关文档和资源。

正文完