一尘不染

Mac上的Docker机器:在docker主机/ docker-machine上看不到已装载的卷?卷物理存储在哪里?

docker

我在一台Macbook Pro笔记本电脑上运行 docker-machine(0.5.0)docker-compose(1.5.0)
以启动我的容器。

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

我认为我缺少关于HOSTS和VOLUME概念的关键内容,因为它们涉及Docker和文档。

这是我的docker-compose.yml文件(网络只是构建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 Compose文件文档在这里:http :
//docs.docker.com/compose/compose-
file/

它说明了卷-将 路径作为卷安装,可以选择在主机上指定路径(HOST:CONTAINER)或访问方式(HOST:CONTAINER:ro)。

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

网络下, 我声明:

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

会将 我的 Macbook Pro 上的本地 Macbook 文件系统 ./src
文件夹映射到我的Web容器。如果我的理解是正确的,那不应该将我 VM* 上的 ./src 文件夹映射到Web容器内的 / var / www /
html
吗?从理论上讲,我认为应该先将本地Mac文件系统文件夹 ./src复制 到我的VM,然后再执行此卷声明。似乎docker-
compose神奇地一次完成了所有工作? 困惑
* __

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

volumes:
   - /var/lib/mysql

这是否不应该在我的HOST boot2docker VM上创建 / var / lib / mysql
文件夹,然后我就可以导航到VM上的该文件夹,是/否?当我使用docker-machine SSH进入我的机器,然后导航到 / var / lib时
,根本 没有 mysql文件夹吗?为什么不创建它?我的配置有问题吗?:/

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


阅读 900

收藏
2020-06-17

共1个答案

一尘不染

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

让我们从泊坞窗卷的内容开始(此时不要尝试考虑您的Macbook或无所事事的机器。请记住泊坞窗使用不同的文件系统(无论此时它可能驻留在何处)):就像这样,Docker内部的每个卷本身只是docker使用的内部文件系统的一部分。容器可以使用这些卷,就像它们是“小型硬盘”一样,可以由它们安装并在它们之间共享(或由它们中的两个同时安装,例如将某些ftp服务器的超快速版本安装到两个客户端上或任何:P)。

原则上,您可以通过Dockerfile的VOLUME指令声明这些卷(仍然不考虑您的计算机/游民本身,只是dockers)。标准示例,运行一个Web服务器容器,如下所示:

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)。让我们讨论一下,就好像我们首先在本机Linux上运行一样。

如果您要输入以下内容:

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

在您的docker-compose.yml中,这意味着/ home / myuser / folder现在将被安装到docker中。它会覆盖docker在/
folder中的所有内容,就像/ www也可以从声明它的东西中访问。现在,正在运行docker daemon的Linux计算机。

理论上是如此:),实际上,您可能只需要以下建议即可开始工作:):

boot2docker / docker-machine /
kitematic和所有这些东西处理问题的方式很简单,它们首先只是将无聊的机器中的一个卷挂载到docker容器上,然后他们也将这个东西挂载到Mac文件系统中,希望一切都能解决:P

现在,对于实际问题,我们所有人在Mac上使用此功能(或只是试图帮助其同事进入甜蜜的Docker:P领域)都面临权限问题。我的意思是考虑一下(root或其他一些用户处理容器中的文件,用户vagrant可能会处理vagrant主机中的文件,然后您的Mac用户“
skalfyfan”会处理Mac中的这些文件。它们都有不同的用户ID和whatnot =

随之而来的是许多问题,并且在一定程度上取决于您在Docker中实际运行的内容。Mysql和Apache尤其痛苦,因为它们不是在容器中以root用户身份运行,这意味着,它们通常难以写入Mac文件系统。

在尝试下面的第二种方法之前,只需尝试将容器卷放在Mac主目录下。随着时间的推移,这将解决大多数情况下MySQL的问题。顺便说一句:
无需声明卷./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

您错了:)如前所述,如果您不提供主机文件夹,则Docker将保留此路径。但是仅针对此容器,所有内容都将保留在docker文件系统中。什么都没有写到主机!仅当在容器文件夹之前指定主机文件夹时,才会发生这种情况!

希望这有帮助:)

2020-06-17