Mount directory in Container and share with Host

2020-01-30 12:18发布

问题:

I thought I understood the docs, but maybe I didn't. I was under the impression that the -v /HOST/PATH:/CONTAINER/PATH flag is bi-directional. If we have file or directories in the container, they would be mirrored on the host giving us a way to retain the directories and files even after removing a docker container.

In the official MySQL docker images, this works. The /var/lib/mysql can be bound to the host and survive restarts and replacement of container while maintaining the data on the host.

I wrote a docker file for sphinxsearch-2.2.9 just as a practice and for the sake of learning and understanding, here it is:

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

Very simple and easy to get your head wrapped around while learning. I am assigning the /etc & /var directories from the sphinx build to the VOLUME command thinking that it will allow me to do something like -v ~/dev/sphinx/etc:/usr/local/sphinx/etc -v ~/dev/sphinx/var:/usr/local/sphinx/var, but it's not, instead it's overwriting the directories inside the container and leaving them blank. When i remove the -v flags and create the container, the directories have the expected files and they are not overwritten.

This is what I run to create the docker file after navigating to the directory that it's in: docker build -t sphinxsearch .

And once I have that created, I do the following to create a container based on that image: docker run -it --hostname some-sphinx --name some-sphinx --volume ~/dev/docker/some-sphinx/etc:/usr/local/sphinx/etc -d sphinxsearch

I really would appreciate any help and insight on how to get this to work. I looked at the MySQL images and don't see anything magical that they did to make the directory bindable, they used VOLUME.

Thank you in advance.

回答1:

After countless hours of research, I decided to extend my image with the following 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"]

Extending it benefited it me in that I didn't have to build the entire image from scratch as I was testing, and only building the parts that were relevant.

I created an ENTRYPOINT to execute a bash script that would copy the files back to the required destination for sphinx to run properly, here is that code:

#!/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 "$@"

Having access to the /etc & /var directories on the host allows me to adjust the files while keeping them preserved on the host in between restarts and so forth... I also have the data saved on the host which should survive the restarts.

I know it's a debated topic on data containers vs. storing on the host, at this moment I am leaning towards storing on the host, but will try the other method later. If anyone has any tips, advice, etc... to improve what I have or a better way, please share.

Thank you @h3nrik for suggestions and for offering help!



回答2:

Mounting container directories to the host is against the docker concepts. That would break the process/resources encapsulation principle.

The other way around - mounting a host folder into a container - is possible. But I would rather suggest to use volume containers, instead.



回答3:

because mysql do init After the mapping,so before mapping there have no data at /var/lib/mysql.

so if you have data before start container, the -v action will override your data.

see entrypoint.sh



标签: docker