我以为我理解了文档,但也许我没有。我的印象是-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
学习时非常简单易学。我正在分配/ etc&从sphinx构建到VOLUME命令的/ var目录认为它允许我执行类似-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。
提前谢谢。
答案 0 :(得分:15)
经过无数个小时的研究,我决定使用以下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提供建议并提供帮助!
答案 1 :(得分:5)
将容器目录挂载到主机是违反docker概念的。这将破坏流程/资源封装原则。
另一种方法是 - 将主机文件夹安装到容器中 - 是可能的。但我宁愿建议使用volume containers,而不是。
答案 2 :(得分:0)
因为mysql会执行init,所以在映射之后,因此/ var / lib / mysql中没有数据。
因此,如果在启动容器之前有数据,则-v操作将覆盖您的数据。
请参阅entrypoint.sh