13

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

这意味着我正在使用 docker-machine 创建我的 virtualbox boot2docker 驱动的主机,它将运行我的 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 Compose 卷的文件文档在这里:http ://docs.docker.com/compose/compose-file/

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

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

网络下我声明:

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

这是将我的 macbook pro 上的本地 macbook 文件系统./src文件夹映射到我的 Web 容器。如果我的理解是正确的,它不应该将我的虚拟机上的./src文件夹映射到Web 容器中的/var/www/html吗?!从理论上讲,我认为我应该首先将我的本地 mac 文件系统文件夹./src 复制到我的虚拟机,然后我执行此卷声明。似乎 docker-compose 神奇地一次完成了这一切?使困惑

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

volumes:
   - /var/lib/mysql

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

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

4

1 回答 1

12

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

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

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

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 守护进程的 Linux 机器。

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

boot2docker/docker-machine/kitematic 和所有这些东西处理这个问题的方式很简单,它们首先将 vagrant 机器中的一个卷挂载到 docker 容器中,然后它们也简单地将这个东西挂载到你的 Mac 文件系统中,希望一切都会好起来:P

现在对于我们所有人在 Mac 上使用这个(或者只是试图帮助他们的同事进入甜蜜甜蜜的 Docker 世界:P)所面临的实际问题是权限。我的意思是考虑一下(root 或其他一些用户处理容器中的文件,用户 vagrant 可能会处理 vagrant 主机中的文件,然后您的 Mac 用户“skalfyfan”在 Mac 中处理这些文件。它们都有不同的用户 ID 和诸如此类 = > 随之而来的许多问题,在某种程度上取决于您在 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 复制到我的虚拟机,然后我执行此卷声明。似乎 docker-compose 神奇地一次完成了这一切?

没错,它就是这样做的:)

最后,我们可以看到我正在创建一个仅数据容器来保存我的 mysql 数据。我已经声明:卷:- /var/lib/mysql

这个你错了:) 如前所述,如果你不提供主机文件夹,那么 Docker 将保留这个路径。但仅针对此容器,所有容器都将保留在 docker 文件系统中。根本没有写给主机!只有在容器文件夹之前提供主机文件夹时,才会发生这种情况!

希望这有帮助:)

于 2015-11-06T21:45:52.320 回答