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

编辑 :我不再使用docker,所以我不能够testing这个问题的答案

感谢所有的build议!


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

嗨,

理解卷的工作方式我有一些困难。

我已经阅读了Dockerfile的参考资料 ,同时也了解了卷

我正在尝试做什么

  • 我有一个图像,使运行WordPress的composer php安装到/ var / tmp / html
  • 那么ONBUILD我使用docker-compose.yml ENVIRONMENTvariables中的一些信息来做一些更多的操作到/ var / tmp / html
  • 作为最后一步,我希望一切都被复制到/ var / www / html,让它可以从composer php(能够运行Apache指向这些文件),从本地文件系统(我将代码的东西这个HTML目录)

我现在有什么

testing1

Dockerfile

泊坞窗,compose.yml

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

这个testing只是安装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 

很好

并在本地文件系统上列出./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 

这是错误的,但完全预期。 容器上的文件是可以的,但在容器外没有任何事情要做,因为我没有提供任何容量信息。

testing2

Dockerfile

泊坞窗,compose.yml

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

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

这是差异的粘贴

Dockerfile

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

泊坞窗,compose.yml

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

构build映像并运行cointainer的结果既是容器上的空html目录,也不改变本地文件系统

谢谢!

编辑:我已经创build了这个问题的最小失败版本: 如何获得本地文件系统上的docker容器生成的内容(最小的失败示例)

我想你对Dockerfile中的VOLUME有什么小小的误解,当你运行一个docker容器的时候-v会做什么。

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

例:

我们有一个文件testing文件在/ 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容器中安装这个目录,所以当我们改变主机上的一个文件时,它会在容器内改变。

这就是你现在正在做的事情(在/home/test容器里创build一个空的VOLUME ):

Dockerfile

 FROM ubuntu:14.04 VOLUME /home/test 

构build这个图像并从中运行一个容器:

 $ 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 ../ 

你实际上想要做的是在docker run时使用-v

Dockerfile

 FROM ubuntu:14.04 

构build这个图像并从中运行一个容器:

 $ 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 

编辑

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

例:

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 ../ 

但是如果你把完整的path:

泊坞窗,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 

卷像挂载点一样起作用,所以当挂载卷时,挂载点的内容是到达容器的内容。

正如在这个(简化的)问题中所回答的,解决scheme是在一个入口点上执行操作,该入口点将在挂载卷之后执行。

看看您的Dockerfile和docker-compose.yml文件的版本2,我build议进行以下编辑:

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为正在运行的脚本(以及login到容器时)设置默认path。

在你的第一个例子中,你使用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