【问题标题】:How to get contents generated by a docker container on the local fileystem如何在本地文件系统上获取 docker 容器生成的内容
【发布时间】:2016-01-21 12:35:39
【问题描述】:

编辑:我不再使用 docker,所以我无法测试这个问题的答案

感谢大家的建议!


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

这是好的

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

这是差异的粘贴

Dockerfile

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

docker-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)

【问题讨论】:

  • this other question 有帮助吗?
  • 我认为不是。它确实提供了“将文件放在那里”的解决方案,但我正在为 Web 开发建立一个基础,所以我真的需要在本地和容器文件系统之间共享文件。谢谢!

标签: docker dockerfile docker-compose


【解决方案1】:

我认为您对Dockerfile 中的VOLUME 的作用以及运行docker 容器时-v 的作用存在一些误解。

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

例子:

我们在 /home/test/ 中有一个文件 test-file

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 的容器内创建一个空的 VOLUME):

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

你真正想做的是在docker run时使用-v

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

编辑

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

例子:

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

但是如果你把完整的路径:

docker-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

【讨论】:

  • 是的,你对我的误解是正确的。没有办法在 docker-compose 声明中获取 -v 功能吗?我正在尝试在 tutum 上建立一个自建环境,它依赖于它们。非常感谢您的回答
  • 抱歉,我只是在检查自己的事实-我认为您的问题是您的docker-compose.yml 文件中没有: 两侧的完整路径。我会更新我的答案。
【解决方案2】:

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

正如this (simplified) question 中回答的那样,解决方案是在一个入口点上执行操作,该入口点将在卷安装后执行。

【讨论】:

    【解决方案3】:

    查看 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 的内容复制到自身,然后您将该目录放入 bin。另外,这个目录不会暴露在容器之外。

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

    Docker-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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2014-01-15
      • 1970-01-01
      相关资源
      最近更新 更多