我是 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。
答案 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
手动执行此操作或在容器代码中使用某种方法来执行此操作。