';撤消';或';取消';用于在注册表中共享mysql数据库的dockerfile卷

';撤消';或';取消';用于在注册表中共享mysql数据库的dockerfile卷,mysql,docker,dockerfile,Mysql,Docker,Dockerfile,我从mysql Dockerfile继承,希望将卷(/var/lib/mysql)移回容器中,以便从注册表分发它 在我的下游Dockerfile中是否有方法(a)撤消卷声明或(b)用符号链接替换/var/lib/mysql?不要将数据库数据发送到与数据库相同的映像中!这是一种反模式,几乎会立即产生更大的问题。将数据作为存档单独发送,然后通过绑定装载(-v/home/foo/db:/var/lib/mysql)将其装载到数据库容器中。docker run语句中的绑定装载卷将覆盖任何VOLUMEDo

我从mysql Dockerfile继承,希望将卷(/var/lib/mysql)移回容器中,以便从注册表分发它


在我的下游Dockerfile中是否有方法(a)撤消卷声明或(b)用符号链接替换/var/lib/mysql?

不要将数据库数据发送到与数据库相同的映像中!这是一种反模式,几乎会立即产生更大的问题。将数据作为存档单独发送,然后通过绑定装载(
-v/home/foo/db:/var/lib/mysql
)将其装载到数据库容器中。
docker run
语句中的绑定装载卷将覆盖任何
VOLUME
Dockerfile指令。或者,创建一些自动化来转储数据库并将其发送到容器中,然后使用转储进行恢复。无论您做什么,都比使用数据库映像中的数据创建映像要好。举个例子说明为什么这是个坏主意:当您需要移动现在已经发生更改的数据/数据库时会发生什么?您可能会使用
docker export
将整个容器的文件系统转储到一个新映像中,而现在您正在传递一大团难以审核的垃圾。Docker容器(和一般的微服务)被设计成短暂的和无状态的,这意味着你可以用软管连接任何一个容器并重新创建它,它将继续工作。如果在数据库映像中发送数据块,则无法执行此操作


关于该docker文件中的
VOLUME
指令:请记住,docker文件是在
docker build
期间使用的,因此不(也不能)包含依赖于主机的信息或操作。因此,
VOLUME/var/lib/mysql
并没有使您的图像无法分发。什么是创建一个通用(即非绑定装载)数据卷,该数据卷将该目录的数据保存到容器的生命周期之外。它与绑定装载卷不同,例如在
docker run-v”/var/docker/app/data:/var/lib/mysql“…
中。此Dockerfile指令不会阻止您分发映像,因为它没有指定依赖于主机的信息。

我放弃这一点——分发DB数据目录的压缩副本似乎更简单。如果你有更好的选择,请发表。

我也有同样的问题,只是有另一个数据库(arangodb)

但是,我没有找到这个问题的直接解决方案,但在我的情况下(这也应该适用于mysql),我只是将数据库的数据目录更改为Dockerfile中的非卷目录


目前,这似乎是最好的解决方案,因为您可以构建包含数据的完整映像。

正如L0j1k生动地论证的那样,将数据目录放在容器中是一个非常糟糕的主意。然而,在某些情况下,这是有意义的。与自动测试一样,运行一个包含testdata的容器,检查所有内容是否按预期工作,然后将其丢弃。此外,在OSX和Windows上,卷不是本机堆(因为docker在VM中运行),它们的速度可能非常慢。因此,根据您的情况,您最好将数据从容器中复制到容器中

虽然无法撤消VOLUME指令,但只需创建一个新的data dir并告诉Mysql使用它:

FROM mariadb:latest

# Create data dir in /var/lib/data
RUN mkdir /var/lib/data
RUN chown mysql.mysql /var/lib/data

# Change data dir from /var/lib/mysql to /var/lib/data
RUN sed -i 's/\/var\/lib\/mysql/\/var\/lib\/data/g' /etc/mysql/my.cnf

小心使用。

这会使数据库的数据目录无法从注册表中分发。我知道构建的映像仍然可以被推拉,但是没有数据在里面,这对我没有帮助。你是在暗示你要在映像里面发送数据库目录吗?我的朋友,那些水域里有很多鱼翅。我也有同样的问题,但对于PHP,base image有VOLUME/var/www/html,我想在build中的这个目录中添加应用程序源代码。它有
WORKDIR/var/www/html
。这与
不同。
WORKDIR
的效果实际上就像
cd
命令一样,它只是使该位置成为您的pwd。您可以将该目录中的文件作为映像的一部分发送。这里的许多人建议将数据库数据与数据库映像一起发送,这是一种反模式。不要将数据库数据放在数据库映像中。站点的源文件(如
/var/www/html
)是没有问题的,因为它们是无状态的,但必须明确指出数据库数据(如
/var/lib/mysql
)应该单独发送。刚接触Docker和microservice体系结构的人认为这是在一个映像中传送数据和数据库的正确答案,但事实并非如此。发布给任何未来的查看者时,不要在数据库映像中传送数据库数据块。这是一种反模式,几乎会立即给您带来问题。要做到这一点,“正确”的方法是提供转储并随转储一起恢复,或者提供数据blob的存档/zip(并从主机装载到容器中),如本文所述,或者提供任何其他保持容器映像干净和可审核的方法。