如何在本地文件系统上获取docker容器生成的内容

时间:2016-01-21 12:35:40

标签: docker dockerfile docker-compose

编辑:我不再使用泊坞广告,因此我无法测试此问题的答案

感谢大家的建议!

  

TL; DR:你能指点我写一个图像的简单例子吗?   更改容器和主机之间共享的卷   文件系统?

您好,

我无法理解卷的工作原理。

我已阅读Dockerfile referenceunderstanding volumes

我正在尝试做什么

  • 我有一个图像,使作曲家在RUN上安装wordpress到/ var / tmp / html
  • 然后ONBUILD我使用docker-compose.yml环境变量中的一些信息对/ var / tmp / html进行更多操作
  • 作为最后一步,我希望将所有内容复制到/ var / www / html并让它从作曲家(能够运行指向这些文件的apache)和本地文件系统(我会将内容编写为html目录)

我现在拥有什么

测试1

Dockerfile

docker-compose.yml

上面的链接是指向这些文件的github上特定版本的链接

此测试只是安装wordpress而无需任何音量信息的所有内容

结果

攻击图像并列出/ var / www / html

我明白了:

root@4484ccdb63ca:/var/www/html# ls -al
total 32
drwxr-xr-x 6 www-data www-data 4096 Jan 21 11:45 .
drwxr-xr-x 6 root     root     4096 Jan 21 11:45 ..
-rw-r--r-- 1 www-data www-data   10 Jan 21 10:47 .gitignore
-rw-r--r-- 1 www-data www-data  138 Jan 21 10:47 composer.json
-rw-r--r-- 1 www-data www-data 3718 Jan 21 10:47 composer.lock
-rw-r--r-- 1 www-data www-data  428 Jan 21 10:47 index.php
drwxr-xr-x 6 www-data www-data 4096 Jan 21 11:45 vendor
drwxr-xr-x 8 www-data www-data 4096 Jan 21 11:45 wordpress

ok

并在我得到的本地文件系统上列出./html

total 0
drwxr-xr-x   3 miqueladell  staff  102 Jan 21 10:33 .
drwxr-xr-x  11 miqueladell  staff  374 Jan 21 13:04 ..
-rw-r--r--   1 miqueladell  staff    0 Jan 21 10:33 foo

错误,但完全可以预料到。

表示容器外的文件没有问题,因为我没有提供任何卷信息。

测试2

Dockerfile

docker-compose.yml

上面的链接是指向这些文件的github上特定版本的链接

在Dockerfile和docker-compose.yml上添加VOLUME

这是diff

的粘贴

Dockerfile

- # VOLUME /var/www/html/
+ VOLUME /var/www/html/

搬运工-compose.yml

-  # volumes:
-  #    - .html:/var/www/html/
+  volumes:
+     - ./html:/var/www/html/

构建映像并运行cointainer的结果是空的容器上的空html目录并且没有更改本地文件系统

谢谢!

编辑:我已创建此问题的最小失败版本:How to get contents generated by a docker container on the local fileystem (minimal failing example)

3 个答案:

答案 0 :(得分:0)

我认为您对VOLUME中的Dockerfile以及运行泊坞广告容器时-v所做的事情有一点误解。

VOLUME和-v之间的根本区别在于:-v将在您的docker容器中挂载操作系统中的现有文件,而VOLUME将在您的主机上创建一个新的空卷(已存储)在/ var / lib / docker / xxxxx中)并将其安装在容器中。

示例:

我们在/ home / test /

中有一个文件测试文件
cmckinnel at arch in /home/test
$ ll
total 8
drwxr-xr-x 2 cmckinnel adm  4096 Jan 21 14:40 .
drwxr-xr-x 4 root      root 4096 Jan 21 14:40 ..
-rw-r--r-- 1 cmckinnel adm     0 Jan 21 14:40 test-file

我们想在docker容器中挂载这个目录,所以当我们更改主机上的文件时,它会在容器内部发生变化。

这就是您目前正在做的事情(在VOLUME处的容器内创建一个空的/home/test):

Dockerfile

FROM ubuntu:14.04

VOLUME /home/test

构建此图像并从中运行容器:

$ docker build -t test-creating-volume .
$ docker run -ti test-creating-volume bash
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 14:41 ./
drwxr-xr-x 3 root root 4096 Jan 21 14:41 ../

您实际想要做的是在-v

时使用docker run

Dockerfile

FROM ubuntu:14.04

构建此图像并从中运行容器:

$ docker build -t test-mounting-volume .
$ docker run -ti -v /home/test:/home/test test-mounting-volume bash
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 1000 adm  4096 Jan 21 14:40 ./
drwxr-xr-x 3 root root 4096 Jan 21 14:51 ../
-rw-r--r-- 1 1000 adm     0 Jan 21 14:40 test-file

修改

糟糕,我认为您上面的实际问题是,您的volume:文件中的docker-compose.yml声明中没有完整的路径。

示例:

docker-compose.yml(注意.home不存在)

test-mounting-volume:
    image: test-mounting-volume:
    volumes:
        - .home:/home/test

然后:

$ docker-compose run test-mounting-volume
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 15:01 ./
drwxr-xr-x 3 root root 4096 Jan 21 15:01 ../

但如果你把完整的路径:

搬运工-compose.yml:

test-mounting-volume:
    image: test-mounting-volume:
    volumes:
        - /home/test:/home/test

然后:

$ docker-compose run test-mounting-volume
$ cd /home/test
$ ll
total 8
drwxr-xr-x 2 root root 4096 Jan 21 15:01 ./
drwxr-xr-x 3 root root 4096 Jan 21 15:01 ../
-rw-r--r-- 1 1000 adm     0 Jan 21 14:40 test-file

答案 1 :(得分:0)

卷的功能类似于挂载点,因此在挂载卷时,挂载点的内容就是到达容器的内容。

正如在this (simplified) question中所解释的那样,解决方案是在挂载卷之后执行操作。

答案 2 :(得分:0)

查看Dockerfile和docker-compose.yml文件的第2版,我建议进行以下编辑:

<强> Dockerfile

第70行:改变

WORKDIR /tmp/html

ONBUILD RUN rsync --ignore-existing -a /tmp/html/ .

WORKDIR /var/www/html

ONBUILD RUN rsync --ignore-existing -a /tmp/html/ .

WORKDIR设置正在运行的脚本的默认路径(以及登录容器时)。

在您的第一个示例中,您正在使用rsync将/tmp/html的内容有效地复制到自身,然后再将该目录存入。此外,此目录不会暴露在容器外部。

通过上述更改,您将/tmp/html的内容复制到/var/www/html,然后将其暴露在容器外部,然后使用docker-compose文件映射到本地计算机。

<强>多克尔-compose.yml

尝试以下文件:

wordpress:
image: miqueladell/composed_wordpress_test
links:
    - wordpress_db:mysql
environment:
    - VIRTUAL_HOST=miqueladell.dev
    - WORDPRESS_DB_NAME=wordpress
ports:
    - "80:80"
  volumes:
   - ./html:/var/www/html

wordpress_db:
  image: miqueladell/mariadb-utf8mb4
  environment:
     - MYSQL_ROOT_PASSWORD=password