使用docker图像 mysql:5.7.21
我想创建一个新的图像的基础上,它将已经有了它的数据库初始化(我想把它用于我的接受环境)。
我知道那件事 /docker-entrypoint-initdb.d
我可以做休养:
FROM mysql:5.7.21
COPY ./init /docker-entrypoint-initdb.d
但问题是,它只会复制tar/sql文件,但在第一次运行之前不会执行。另一个缺点是图像大小。如果在容器中复制例如200mb的数据,那么这些文件将保留在图像中(作为一个层)。
所以我想知道是否有一个我没有想到的与multi-stage或新的--squash标志的组合(可以启用,添加文件,执行文件,删除文件)。
在我寻找这个问题的过程中,我还发现 --datadir
旗帜。不知道这有什么用。
编辑:
到目前为止,我有以下几点:
FROM mysql:5.7.21 as builder
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example
COPY ./init /docker-entrypoint-initdb.d
RUN head -n-2 < /usr/local/bin/docker-entrypoint.sh > /usr/local/bin/docker-entrypoint.sh \
&& docker-entrypoint.sh mysqld \
&& /etc/init.d/mysql start \
&& mysql -uroot -e 'FLUSH TABLES;' \
&& mysql -uroot -e 'show tables;' mysql \
&& mysql -uroot -e 'show tables;' example \
&& /etc/init.d/mysql stop \
# This shows the files!
&& ls -la /var/lib/mysql
# This shows no files?!!
RUN ls -la /var/lib/mysql
FROM mysql:5.7.21
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example
COPY --from=builder /var/lib/mysql /var/lib/mysql
RUN ls -la
RUN ls -la /var/lib/mysql \
&& /etc/init.d/mysql start \
&& mysql -uroot -e 'show tables;' mysql \
&& mysql -uroot -e 'show tables;' example
请参阅上面的内联注解。。。有什么奇怪的事情发生了?所以在同一次运行中,当我执行 ls -la
在 /var/lib/mysql
我能看到文件。但在新层(新运行)中,它是空的:s
2条答案
按热度按时间vhmi4jdf1#
所以我找到了解决办法!!!我的问题在于/var/lib/mysql是一个卷:https://github.com/docker-library/mysql/blob/ad625c64a06e16683e997e5a0147508d115f4989/5.7/dockerfile#l71
工作的多级dockerfile:
因此,我们在这里要做的是确保删除最后2行(可以更改为仅删除最后一行),因为它包含
exec "$@"
基本上就是说exec msqld
. 这是mysql的执事,所以它会被卡在那里。此外,我将datadir从
var/lib/mysql
(这是一卷)到var/lib/mysql_tmp
(因为没有更好的名字)。在最后阶段我复制了
var/lib/mysql_tmp
确保mysqld使用这个dir。现在我可以烘烤(我只读)db的我的接受环境。
xqnpmsa82#
如果你检查了dockerfile的
mysql:5.7.21
图像(https://hub.docker.com/r/library/mysql/),您将看到入口点设置为["docker-entrypoint.sh"]
,因此这是运行映像时执行的第一个命令。如果您想在图像创建期间执行它(因此,使图像大小变大,但可以),您只需将其放入dockerfile中:
此入口点将执行在中找到的脚本
/docker-entrypoint-initdb.d
但是,正如您所注意到的,脚本也占用了空间。为了丢弃这些文件,可以使用多级构建来复制原始数据库。再次检查dockerfile以查看图像中唯一的卷是
/var/lib/mysql
. 这应该是包含数据库中所有信息的目录,它应该是您复制的内容。结果是这样的:尽管如此,我不建议创建“初始化”图像,因为这有点违背容器使用的精神,但这是另一个问题;)