为什么docker容器里有的目录可以挂载共享文件,有的不能

时间:2021-06-11 09:02:55

标签: docker dockerfile docker-image

我是 docker 的新手。我在尝试制作自己的 docker 镜像时遇到了一个问题。 事情就是这样。我创建了一个新的 DockerFile 来构建我自己的 mysql 映像,我在其中声明了 MYSQL_ROOT_PASSWORD 并在容器中放置了一些初始化脚本。 这是我的 Docker

FROM mysql:5.7
MAINTAINER CarbonFace<553127022@qq.com>
ENV TZ                      Asia/Shanghai
ENV MYSQL_ROOT_PASSWORD     Carbon@mysqlRoot7
ENV INIT_DATA_DIR           /initData/sql
ENV INIT_SQL_FILE_0         privileges.sql
ENV INIT_SQL_FILE_1         carbon_user_sql.sql
ENV INIT_SQL_FILE_2         carbonface_sql.sql
COPY ./my.cnf /etc/mysql/donf.d/
RUN mkdir -p $INIT_DATA_DIR
COPY ./sqlscript/$INIT_SQL_FILE_0 $INIT_DATA_DIR/
COPY ./sqlscript/$INIT_SQL_FILE_1 $INIT_DATA_DIR/
COPY ./sqlscript/$INIT_SQL_FILE_2 $INIT_DATA_DIR/
COPY ./sqlscript/$INIT_SQL_FILE_0 /docker-entrypoint-initdb.d/
COPY ./sqlscript/$INIT_SQL_FILE_1 /docker-entrypoint-initdb.d/
COPY ./sqlscript/$INIT_SQL_FILE_2 /docker-entrypoint-initdb.d/
CMD ["mysqld"]

我正在尝试构建一个包含我自己的配置文件的 docker 镜像,安装后它将显示在本地目录中并且可以修改。 我真的很困惑,当我使用官方描述的这个图像启动我的容器时,这里是我的命令:

docker run -dp 3306:3306 \
-v /usr/local/mysql/data:/var/lib/mysql \
-v/usr/local/mysql/conf:/etc/mysql/conf.d \
--name mysql mysql:<my builded tag>

你知道我正在尝试安装 /usr/local/mysql/conf 到容器中的 /etc/mysql/conf.d,它被告知是自定义配置文件的安装位置。
我认为我的自定义配置文件 my.cnf 在 docker build 期间已复制到图像中,并将显示在我的本地目录中 /usr/local/mysql/conf
因为我已经将我的自定义配置文件复制到你可以在我的 DockerFile 中看到的图像中。 但是结果发现目录是空的,/etc/mysql/conf.d也被本地目录覆盖了。
在我运行我的容器之前,/usr/local/mysql/conf/usr/local/mysql/data 都是空的。
好的,我被告知卷挂载目录会覆盖容器内的文件。
但是空数据目录怎么会显示容器内的数据文件,但是空的conf目录会覆盖容器内的conf.d目录。
这没有任何意义。 我很困惑,如果有人能解释为什么会这样,我将不胜感激。

我的操作系统是 MacOS Big Sur,我使用了最新的 docker。

1 个答案:

答案 0 :(得分:0)

主机目录绑定挂载,-v /host/path:/container/path总是隐藏图像的内容并将其替换为主机目录。如果宿主目录为空,则容器目录将是容器启动时相同的空目录。

Docker Hub mysql 容器具有 an involved entrypoint script,用于检查数据目录是否为空,如果是,则初始化数据库;抽象出来

#!/bin/sh
# (actually in hundreds of lines of shell code, with more options)
if [ ! -d /var/lib/mysql/data/mysql ]; then
  mysql_install_db
  # (...and start a temporary database server and run the
  # /docker-entrypoint-initdb.d scripts)
fi

# then run the main container command
exec "$@"

仅仅存在卷不会导致文件被复制(命名卷的生命周期中的一个特定点除外),因此如果您需要将内容从容器复制到主机,您要么需要使用 docker cp 手动执行此操作或在容器代码中使用某种方法来执行此操作。