简体   繁体   English

撤消或取消dockerfile卷以在注册表中共享mysql数据库

[英]'undo' or 'cancel' dockerfile VOLUME to share mysql DB in registry

I'm inheriting from the mysql Dockerfile and want to move a VOLUME (/var/lib/mysql) back inside the container so I can distribute it from a registry. 我从mysql Dockerfile继承而来,想将VOLUME(/ var / lib / mysql)移回容器内,以便可以从注册表中分发它。

Is there a way in my downstream Dockerfile to (a) undo the VOLUME declaration or (b) replace /var/lib/mysql with a symlink? 我的下游Dockerfile中是否有办法(a)撤消VOLUME声明或(b)用符号链接替换/ var / lib / mysql?

I'm giving up on this -- seems simpler to distribute a zipped copy of the DB data directory. 我放弃了-分发DB数据目录的压缩副本似乎更简单。 If you have a better option, please post. 如果您有更好的选择,请发表。

I had the exact same problem, just with another database (arangodb). 我有完全相同的问题,只是另一个数据库(arangodb)。

However, I did not find a direct solution for this problem, but in my case (this should also work with mysql), I simply changed the data directory of my database to a non-volume directory in the Dockerfile. 但是,我没有找到直接解决此问题的方法,但就我而言(这也适用于mysql),我只是将数据库的数据目录更改为Dockerfile中的非卷目录。

For now, this seems like the best solution, as you can build a full image that contains your data. 目前,这似乎是最好的解决方案,因为您可以构建包含数据的完整映像。

As L0j1k has argued vividly in general it is a very bad idea to have your data dir inside of the container. 通常,L0j1k争论得很清楚,将您的数据目录放在容器中是一个非常糟糕的主意。 However there are situations where it makes sense. 但是,在某些情况下这很有意义。 Like for automated tests, run a container with testdata check that everything works as expected and throw it away. 像自动测试一样,运行带有testdata的容器,检查一切是否按预期进行,然后将其丢弃。 Also on OSX & Windows volumes aren't native mounds (because docker runs in a VM) and they can be painfully slow. 同样在OSX和Windows上,卷不是本地堆(因为docker在VM中运行),它们的速度可能很慢。 So you might be better of with copying your data from and to the container, depending on your situation. 因此,根据情况,最好在容器之间来回复制数据。

While you can't undo the VOLUME directive you can simply create a new data dir and tell Mysql to use that: 虽然无法撤消VOLUME指令,但是您可以简单地创建一个新的数据目录并告诉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

Use with caution. 请谨慎使用。

DO NOT ship your database data in the same image as your database! 不要以与数据库相同的图像来运送数据库数据! This is an antipattern and will create bigger problems almost immediately. 这是一种反模式,几乎会立即产生更大的问题。 Ship the data separately as an archive which you then mount into your database container via bind-mount ( -v /home/foo/db:/var/lib/mysql ). 单独将数据作为归档发送,然后通过绑定安装( -v /home/foo/db:/var/lib/mysql )将其装入数据库容器。 Bind-mount volumes in your docker run statement will override any VOLUME Dockerfile directive. docker docker run语句中的绑定装入卷将覆盖任何VOLUME Dockerfile指令。 Alternatively, create some automation to dump the database and ship that to your containers, then restore using the dump. 或者,创建一些自动化操作以转储数据库并将其运送到您的容器,然后使用转储进行还原。 Whatever you do will be better than creating an image with your data in the database image. 无论做什么,都比在数据库映像中创建包含数据的映像更好。 Just as one example of why this is a bad idea: What happens when you need to move the data/database mutant which now has changes? 举一个为什么这是个坏主意的例子:当您需要移动现在已经更改的数据库/数据库变量时,会发生什么? You'll probably use docker export to dump the entire container's filesystem into a new image, and now you're passing around a big blob of crap which is hard to audit. 您可能会使用docker export将整个容器的文件系统转储到新的映像中,现在您正在绕过一大堆废话,这很难审核。 Docker containers (and microservices in general) are designed to be ephemeral and stateless, which means you can hose any one container and recreate it and it'll continue working. Docker容器(和一般的微服务)设计为临时的和无状态的,这意味着您可以使用任意一个容器重新创建它,然后它将继续工作。 You can't do this if you ship your blob of data inside the database image. 如果将数据块运送到数据库映像中,则无法执行此操作。

With respect to the VOLUME directive in that Dockerfile: Remember that Dockerfiles are used during docker build and therefore do not (and cannot) contain host-dependent information or actions. 关于该Dockerfile中的VOLUME指令:请记住,Dockerfile在Docker docker build期间使用,因此不(也不能)包含与主机相关的信息或操作。 So the VOLUME /var/lib/mysql isn't making your image impossible to distribute. 因此, VOLUME /var/lib/mysql不会使图像无法分发。 What that directive does is create a generic (ie non-bind-mount) data volume that persists the data of that directory beyond the lifetime of the container. 该指令的作用是创建一个通用(即非绑定安装)数据卷,该数据卷在容器的生存期之外仍保留该目录的数据。 It is not the same thing as a bind-mount volume for example in docker run -v "/var/docker/app/data:/var/lib/mysql" ... . 它是一样的东西在绑定贴装量例如docker run -v "/var/docker/app/data:/var/lib/mysql" ... This Dockerfile directive does not prevent you from distributing the image because it does not specify host-dependent information. 该Dockerfile指令不会阻止您分发映像,因为它未指定与主机相关的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM