问题 Mac上的Docker Machine:在docker主机/ docker-machine上看不到挂载的卷?体积存储在哪里?


我在Macbook Pro笔记本电脑上运行 码头机(0.5.0) 和 docker-compose(1.5.0) 让我的容器运行

这意味着我正在使用docker-machine来创建我的虚拟机boot2docker驱动的HOST机器,它将运行我的docker守护程序并托管我的所有容器。

我想我错过了一些关于HOSTS和VOLUME概念的东西,因为它们指的是Docker和文档。

这是我的docker-compose.yml文件(web只是构建了php:5.6-apache图像):

web:
  restart: "always"
  build: ./docker-containers/web
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www/html
  links:
    - mysql:mysql

mysql:
  restart: "always"
  image: mysql:5.7
  volumes_from:
    - data
  ports:
    - "3306:3306"
  environment:
    - MYSQL_ROOT_PASSWORD=XXX

data:
  restart: "no"
  image: mysql:5.7
  volumes:
    - /var/lib/mysql
  command: "true" 

Docker撰写卷的文件文档在这里: http://docs.docker.com/compose/compose-file/

它说明了卷 - 将路径挂载为卷,可选择指定主机上的路径(HOST:CONTAINER)或访问模式(HOST:CONTAINER:ro)。

在这种情况下HOST是指我的由docker-machine创建的VM,对吗?还是我的本地macbook文件系统?在我的VM上将路径挂载到容器?

卷筒纸 我宣布:

volumes:
  - ./src:/var/www/html

这是映射我的本地macbook文件系统 ./src 我的macbook pro上的文件夹到我的web容器。如果我的理解是正确的,不应该映射 ./src 我的文件夹 VM 至 在/ var / www / html等 在网络容器内?!从理论上讲,我认为应该要求我复制我的本地mac文件系统文件夹 ./src 首先到我的VM,然后我做这个卷声明。似乎docker-compose一下子神奇地做了所有这一切? 困惑

最后,我们可以看到我正在创建一个仅限数据的容器来保存我的mysql数据。我宣布:

volumes:
   - /var/lib/mysql

这不应该创造一个 在/ var / lib中/ MySQL的 我的HOST boot2docker VM上的文件夹然后我可以导航到VM上的这个文件夹,是/否?当我使用docker-machine ssh进入我的机器,然后导航到 在/ var / lib中, 有 没有 mysql文件夹都没有?!为什么没有创建?我的配置有问题吗? :/

提前致谢!任何关于我在这里做错的解释都将不胜感激!


2894
2017-11-06 20:39


起源

是否 stackoverflow.com/questions/23439126/... 回答你的问题? - Eli


答案:


好的,这里有几点需要解决。

让我们从docker卷开始(尝试不要考虑你的macbook或vagrant机器。请注意docker使用不同的文件系统,此时它可能驻留在哪里): 也许想象它就像这样,它本身的每个卷都只是Docker使用的内部文件系统的一部分。 容器可以使用这些卷,就像它们是“小硬盘”一样,可以由它们安装并在它们之间共享(或者同时由两个它们安装,就像将一些ftp服务器的超快版本安装到两个客户端一样或者其他:P)。

原则上你可以通过Dockerfile的VOLUME指令声明这些卷(仍然不考虑你的计算机/流浪者本身,只是码头工人;))。 标准示例,运行一个webserver容器,如下所示:

FROM: nginx
VOLUME /www

现在,进入/ www的所有内容理论上都可以从容器中安装和卸载,也可以安装到多个容器中。 现在单独使用Nginx很无聊,所以我们想让php运行nginx存储的文件以产生更多有趣的内容。 =>我们需要将该卷安装到某个php-fpm容器中。 在我们的撰写文件中,我们会这样做

web:
  image: nginx
php:
  image: php-fpm
  volumes_from:
    - web

瞧瞧!由nginx / web容器中的VOLUME指令声明的每个文件夹都将在php中显示。这里要注意的重要一点,无论是在nginx的/ www中,都将覆盖/ www中的任何php。 如果你把:ro,php甚至无法写入该文件夹:)

现在接近你的问题,有另一种声明卷的方法,它不需要在Dockerfile中声明它们。这可以通过从主机安装卷来完成(在这种情况下你的vagrant / boo2docker thingy)。让我们讨论这个问题,好像我们首先在本机Linux上运行一样。

如果你要做类似的事情:

volumes:
 - /home/myuser/folder:/folder

在您的docker-compose.yml中,这意味着/ home / myuser /文件夹现在将被挂载到docker中。它将覆盖docker在/文件夹中的任何内容,就像/ www也可以从声明它的东西访问它。现在运行docker守护程序的Linux机器。

理论上这么多:),实际上你可能只需要以下建议来让你的东西继续:):

boot2docker / docker-machine / kitematic和所有这些事情处理问题的方式很简单,他们首先只是将流量计算机中的卷安装到docker容器中,并且它们只是将这个东西安装到你的Mac文件系统中,希望一切顺利:P

现在对于实际问题,我们所有人在Mac上使用这个(或者只是试图帮助他们的同事进入甜蜜的Docker:P世界)都面临着权限。我的意思是考虑它(root或其他一些用户处理容器中的文件,用户流浪者可能会处理vagrant主机中的文件,然后你的Mac用户“skalfyfan”处理Mac中的那些文件。他们都有不同的用户ID和whatnot = >随之而来的很多问题,在某种程度上取决于你在Docker中实际运行的内容.Mysql和Apache特别痛苦,因为它们不在容器中以root身份运行。这意味着,他们经常无法写入Mac文件系统。

在尝试下面的第二种方法之前,只需尝试将容器卷放在Mac主目录下。在大多数情况下,这将解决MySQL的问题,因为我已经发现了一段时间。 BTW: 无需声明卷的完整路径./folder很好并且相对于docker-compose.yml所在的位置读取!

只需将compose-yml放入Mac用户文件夹即可,这一切都很重要。没有chmod 777 -R:P会帮助你,它只需要在你的主文件夹下:)

还有一些应用程序(例如Apache)仍会给你带来困难。容器中任何运行的用户ID与Mac用户ID不同的事实将使您的生活变得地狱。为了解决这个问题,您需要以与Mac的权限不冲突的方式调整用户ID和用户组。您在Mac上想要的组是工作人员,工作的UID例如是1000。 因此,您可以将它放在Dockerfile的末尾:

RUN usermod -u 1000 www-data
RUN usermod -G staff www-data

要么

RUN usermod -u 1000 mysql
RUN usermod -G staff mysql

所以你现在学到了:

从理论上讲,我认为应该要求我复制我的本地mac文件   系统文件夹./src首先到我的VM,然后我做这个卷   宣言。似乎docker-compose一下子神奇地完成了这一切   虽然?

对,它确实:)

最后,我们可以看到我正在创建一个仅保留数据的容器   我的mysql数据。我宣布:       卷:           - / var / lib / mysql

这个你错了:)正如所解释的,如果你不给一个主机文件夹,那么Doc​​ker将坚持这条路径。但仅限于此容器,并且所有容器都将保留在docker文件系统中。根本没有任何东西写给主人!只有在容器文件夹之前提供主机文件夹时才会发生这种情况!

希望这有助于:)


12
2017-11-06 21:45



感谢您的解释!关于你的最后评论,如果我在撰写声明卷时没有给出主文件夹你说, 然后Docker将坚持这条道路。 你能澄清它意味着什么吗? 搬运工人 在容器中保留路径?如果它停止,重新启动它将保留数据?只有删除容器才会丢失数据?这是它意味着什么 Docker只在容器中保留路径? - skålfyfan
确切地说:停止是好的,重新启动,数据仍然存在。删除=>数据量也消失了。这里有一个重要的提示:卷仍然存在,但是你失去访问权限并且使用-v标志污染了你的hd => delete容器:) - Armin Braun
最后一个问题!在我的“数据”(仅限数据)容器中,我只是将其更改为: 卷: - / var / test / mysql:/ var / lib / mysql,然后跑了 docker-compose build,docker-compose up -d 重建一切。我希望现在在HOST VM上看到/ var / test / mysql但仍然没有? 头划伤 我现在注意到的一件事是当我通过SSH连接到我的VM时 码头工人  看到所有正在运行的容器, 数据 容器无处可见,即使它正在被创建。也许这是另一个教程... :)谢谢! - skålfyfan
啊等一下:)我想我在boot2docker中解释得很糟糕可能是学习这个的最糟糕的方法! (严重的是,如果您可以通过Vagrant / Virtualbox左右启动Debian或Ubuntu框,并在那里尝试使用少一层文件系统复杂程序:)。无论如何,关于实际问题:我假设您在Mac上运行了docker-compose命令吗?在这种情况下,你需要像我说的那样给出相对于Mac文件系统的路径!此外,卷的所有路径都必须位于Mac用户主文件夹中。否则它将无法工作。 docker ps -a的输出是什么? - Armin Braun
我的Mac上的docker-compose命令正确。我的项目文件夹是我的用户目录中的几个子目录(例如/ Users / myname / dev / projectName)。我只是将我的数据容器更改为: 卷: - ./data/mysql:/var/lib/mysql 其中./data是当前在我本地Mac上的项目文件夹中的空目录。 docker ps -a的输出显示运行的web,mysql容器和 数据 容器 退出(0)X秒前。 - skålfyfan