【问题标题】:Mount directory in Container and share with Host在 Container 中挂载目录并与 Host 共享
【发布时间】:2015-07-30 14:23:12
【问题描述】:

我以为我了解文档,但也许我没有。我的印象是-v /HOST/PATH:/CONTAINER/PATH 标志是双向的。如果容器中有文件或目录,它们将被镜像到主机上,为我们提供了一种方法来保留目录和文件,即使在删除 docker 容器后也是如此。

在官方的 MySQL docker 镜像中,这是可行的。 /var/lib/mysql 可以绑定到主机,并在重启和更换容器的同时保留主机上的数据。

我为 sphinxsearch-2.2.9 写了一个 docker 文件,只是作为练习,为了学习和理解,这里是:

FROM debian

ENV SPHINX_VERSION=2.2.9-release

RUN apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq\
    build-essential\
    wget\
    curl\
    mysql-client\
    libmysql++-dev\
    libmysqlclient15-dev\
    checkinstall

RUN wget http://sphinxsearch.com/files/sphinx-${SPHINX_VERSION}.tar.gz && tar xzvf sphinx-${SPHINX_VERSION}.tar.gz && rm sphinx-${SPHINX_VERSION}.tar.gz

RUN cd sphinx-${SPHINX_VERSION} && ./configure --prefix=/usr/local/sphinx

EXPOSE 9306 9312

RUN cd sphinx-${SPHINX_VERSION} && make

RUN cd sphinx-${SPHINX_VERSION} && make install

RUN rm -rf sphinx-${SPHINX_VERSION}

VOLUME /usr/local/sphinx/etc
VOLUME /usr/local/sphinx/var

在学习时非常简单易懂。我正在将 sphinx 构建中的 /etc 和 /var 目录分配给 VOLUME 命令,我认为它可以让我执行-v ~/dev/sphinx/etc:/usr/local/sphinx/etc -v ~/dev/sphinx/var:/usr/local/sphinx/var 之类的操作,但事实并非如此,而是覆盖容器内的目录并将它们留空。当我删除 -v 标志并创建容器时,目录具有预期的文件并且它们不会被覆盖。

这是我在导航到它所在的目录后运行以创建 docker 文件:docker build -t sphinxsearch .

创建完成后,我将执行以下操作以基于该图像创建一个容器:docker run -it --hostname some-sphinx --name some-sphinx --volume ~/dev/docker/some-sphinx/etc:/usr/local/sphinx/etc -d sphinxsearch

我真的很感激任何关于如何让它发挥作用的帮助和见解。我查看了 MySQL 映像,没有看到他们为使目录可绑定所做的任何神奇操作,他们使用了 VOLUME。

提前谢谢你。

【问题讨论】:

  • 您确实意识到在 Dockerfile 中,“VOLUME /usr/local/sphinx/etc”与 docker run -v /usr/local/sphinx/etc:/usr/local/ 不同sphinx/etc" 不是吗?前者绕过分层文件系统,后者将其映射到您在主机上选择的路径。通常两者一起使用。
  • 是的,我知道这一点。我想从容器访问目录,以便我可以在主机上获取数据。这是我能想到的唯一方法。我在 docker 论坛上发帖并没有得到任何帮助或建议,这是玩弄它并查看无数示例的结果。

标签: docker


【解决方案1】:

经过无数小时的研究,我决定使用以下 Dockerfile 扩展我的镜像:

FROM sphinxsearch

VOLUME /usr/local/sphinx/etc
VOLUME /usr/local/sphinx/var

RUN mkdir -p /sphinx && cd /sphinx && cp -avr /usr/local/sphinx/etc . && cp -avr /usr/local/sphinx/var .

ADD docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

扩展它使我受益,因为我不必在测试时从头开始构建整个图像,而只需构建相关的部分。

我创建了一个 ENTRYPOINT 来执行一个 bash 脚本,该脚本会将文件复制回所需的目的地,以便 sphinx 正常运行,代码如下:

#!/bin/sh
set -e

target=/usr/local/sphinx/etc

# check if directory exists
if [ -d "$target" ]; then
    # check if we have files
    if find "$target" -mindepth 1 -print -quit | grep -q .; then
        # no files don't do anything
        # we may use this if condition for something else later
        echo not empty, don\'t do anything...
    else
        # we don't have any files, let's copy the
        # files from etc and var to the right locations
        cp -avr /sphinx/etc/* /usr/local/sphinx/etc && cp -avr /sphinx/var/* /usr/local/sphinx/var
    fi
else
    # directory doesn't exist, we will have to do something here
    echo need to creates the directory...
fi

exec "$@"

通过访问主机上的 /etc 和 /var 目录,我可以调整文件,同时在重启等期间将它们保留在主机上...我还保存了主机上应该保留的数据重新启动。

我知道这是一个关于数据容器与存储在主机上的争论话题,目前我倾向于存储在主机上,但稍后会尝试另一种方法。如果有人有任何提示、建议等...以改进我所拥有的或更好的方法,请分享。

感谢@h3nrik 的建议和帮助!

【讨论】:

    【解决方案2】:

    将容器目录挂载到主机是违反 docker 概念的。这会破坏进程/资源封装原则。

    另一种方式 - 将主机文件夹安装到容器中 - 是可能的。但我宁愿建议改用volume containers

    【讨论】:

    • 它如何与 MySQL 一起工作并挂载 /var/lib/mysql 目录以将数据持久保存在主机上?我也想做同样的事情。
    • 也许mounting这个词用错了,如何从容器共享一个目录到主机,例如config目录?
    • 只需为/var/lib/mysql 创建一个卷容器:docker run -it --name mysqldata -v /var/lib/mysql mysql /bin/true。然后通过以下方式从您的 mysql 服务容器链接到它:docker run -d --name mysqlserver --volumes-from mysqldata mysql
    • 它的行为类似于 linux 挂载。假设您有一个包含现有文件的目录。然后将一个空磁盘驱动器安装到该目录中。结果将是该目录中存在的文件被挂载“隐藏”并且该目录似乎是空的。绑定的 docker 卷也会发生类似的情况。所以不要将卷挂载到/etc 等。这将隐藏所有以前存在的配置文件。当您只想将一小部分文件提供到/etc 目录中时,请尽可能使用所描述的单个文件挂载。
    • 如果这违背了概念,那么如何在 Docker 中开发应用程序?如果我在每次代码更改后构建 Docker 映像,那么它会很慢。如果我在 Docker 之外运行应用程序,那么它会扼杀 Docker 的优势。
    【解决方案3】:

    因为mysql做init映射后,所以映射前/var/lib/mysql处没有数据。

    所以如果您在启动容器之前有数据,-v 操作将覆盖您的数据。

    查看 entrypoint.sh

    【讨论】:

      猜你喜欢
      • 2021-07-04
      • 1970-01-01
      • 2013-11-13
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多