【问题标题】:Docker -- mounting a volume not behaving like regular mountDocker——挂载一个不像常规挂载的卷
【发布时间】:2017-04-28 13:48:44
【问题描述】:

我是docker 的新手,所以我确定我做错了什么。我也是not a php developer,但在这种情况下应该没关系。

我正在使用drupal docker 镜像,该镜像在/var/www/html 目录中有数据。

我正在尝试使用主机系统上本地目录中的 drupal 站点覆盖此数据。

根据the docs,这是预期的行为

挂载主机目录作为数据卷

除了创建一个 卷使用 -v 标志,您还可以从您的 将 Docker 引擎的主机放入容器中。

$ docker run -d -P --name web -v /src/webapp:/webapp training/webapp python app.py

这个命令挂载主机目录,/src/webapp, 进入 /webapp 的容器。如果路径 /webapp 已经存在 在容器的图像中,/src/webapp 挂载覆盖但确实 不删除预先存在的内容。卸下支架后, 内容可以再次访问。这与预期一致 mount 命令的行为。

但是我发现容器上不存在本地 drupal 站点文件。我的完整工作流程如下:

docker-compose.yml
drupal:
  container_name: empower_drupal
  build: ./build/drupal-local-codebase
  ports:
   - "8888:80"
   - "8022:22"
   - "443"
 #volumes: THIS IS ALSO NOT WORKING
 #- /home/sameh/empower-tap:/var/www/html


$ docker-compose up -d
# edit the container by snapshotting it
$ docker commit empower_drupal empower_drupal1
$ docker run -d -P --name empower_drupal2 -v /home/sameh/empower-tap:/var/ww/html empower_drupal1
# snapshot the container to examine it
$ docker commit 9cfeca48efd3 empower_drupal2
$ docker run -t -i empower_drupal2 /bin/bash

empower_drupal2 容器没有来自/home/sameh/empower-tap 目录的正确文件。

【问题讨论】:

    标签: linux docker drupal docker-compose


    【解决方案1】:

    为什么这不起作用

    这是您所做的,带有一些注释。

    $ docker-compose up -d
    

    鉴于您的 docker-compose.yml,注释掉了 volumes 部分,此时您已运行容器,但未安装卷。

    # edit the container by snapshotting it
    $ docker commit empower_drupal empower_drupal1
    

    您在这里真正所做的只是复制您已经拥有的映像,除非您的容器在启动时对其自身进行更改。

    $ docker run -d -P --name empower_drupal2 -v /home/sameh/empower-tap:/var/ww/html empower_drupal1
    

    在这里您已经运行了新副本,安装了一个卷。好的,文件现在可以在这个容器中使用了。

    # snapshot the container to examine it
    $ docker commit 9cfeca48efd3 empower_drupal2
    

    我在这里假设您想将卷的内容提交到映像中。这是行不通的。 commit documentation 很清楚这一点:

    提交操作将不包括容器内安装的卷中包含的任何数据。

    $ docker run -t -i empower_drupal2 /bin/bash
    

    因此,正如您所发现的,当您运行由commit 生成的映像,但没有安装卷时,文件不存在。

    此外,在您的 docker-compose.yml 示例中,volumes: 部分在被注释掉之前的位置并不清楚。目前它似乎在左边距,这是行不通的。它需要与build:ports: 处于同一级别才能使用您的drupal 服务。

    该怎么做

    这取决于你的目标。

    只需从本地复制文件

    如果您只是想用本地系统中的文件填充映像,您可以在 Dockerfile 中执行此操作。

    COPY local-dir/* /var/www/html
    

    您提到此副本无法工作,因为该目录不是本地目录。不幸的是,使用符号链接之类的东西不能轻易解决这个问题。您最好的选择是在构建之前将目录复制到本地上下文。码头工人does not plan to change this behavior.

    覆盖开发内容

    一个常见的场景是您想使用本地目录进行开发,以便立即反映更改而不是进行重建。但是在不进行开发时,您希望将文件烘焙到图像中。

    在这种情况下,首先告诉 Dockerfile 将文件复制到映像中,如上所述。这样一来,映像构建将包含它们,无论是否安装卷。

    然后,当您进行开发时,使用 docker-compose.yml 中的 volumes: 或 docker run 的 -v 标志来挂载卷。卷安装将覆盖任何烘焙到映像中的内容,因此您将使用本地文件。完成并准备好代码后,只需构建映像,您的最终文件将被烘焙到映像中以进行部署。

    使用卷加提交

    您也可以通过安装卷,将内容复制到其他地方,然后提交结果来稍微迂回地执行此操作。

    # start a container with the volume mounted somewhere
    docker run -d -v /home/sameh/empower-tap:/var/www/html_temp [...etc...]
    
    # copy the files elsewhere inside the container
    docker exec <container-name> cp -r /var/www/html_temp /var/www/html
    
    # commit the result
    docker commit empower_drupal empower_drupal1
    

    那么您应该在生成的映像中包含已安装的卷文件。

    【讨论】:

    • 虽然这是一个很好的解释,但您仍然没有抓住重点。 COPY 无法工作,因为empower-tap 目录位于docker-compose 所在的当前目录之外
    • 另外,如果你仔细阅读 docker-compose,你会发现我已经用 volumes 尝试过,但没有成功
    • @SamHammamy 查看关于两个 cmets 的更新答案;我猜是 docker-compose.yml 因为它被评论了,我不能说它之前的格式是什么。
    • @SamHammamy 我刚刚在底部添加了第三个选项,这看起来更像您在这里尝试做的。
    猜你喜欢
    • 2021-07-16
    • 2016-08-18
    • 2021-10-26
    • 2020-06-05
    • 2020-01-20
    • 2016-02-29
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多