如何创建初始化的mysql docker映像?

ht4b089n  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(278)

使用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

vhmi4jdf

vhmi4jdf1#

所以我找到了解决办法!!!我的问题在于/var/lib/mysql是一个卷:https://github.com/docker-library/mysql/blob/ad625c64a06e16683e997e5a0147508d115f4989/5.7/dockerfile#l71
工作的多级dockerfile:

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
RUN mkdir -p /var/lib/mysql_tmp
RUN docker-entrypoint.sh mysqld --datadir /var/lib/mysql_tmp

FROM mysql:5.7.21

ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example

COPY --from=builder /var/lib/mysql_tmp /var/lib/mysql_tmp

CMD ["mysqld", "--datadir", "/var/lib/mysql_tmp"]

因此,我们在这里要做的是确保删除最后2行(可以更改为仅删除最后一行),因为它包含 exec "$@" 基本上就是说 exec msqld . 这是mysql的执事,所以它会被卡在那里。
此外,我将datadir从 var/lib/mysql (这是一卷)到 var/lib/mysql_tmp (因为没有更好的名字)。
在最后阶段我复制了 var/lib/mysql_tmp 确保mysqld使用这个dir。
现在我可以烘烤(我只读)db的我的接受环境。

xqnpmsa8

xqnpmsa82#

如果你检查了dockerfile的 mysql:5.7.21 图像(https://hub.docker.com/r/library/mysql/),您将看到入口点设置为 ["docker-entrypoint.sh"] ,因此这是运行映像时执行的第一个命令。
如果您想在图像创建期间执行它(因此,使图像大小变大,但可以),您只需将其放入dockerfile中:

RUN docker-entrypoint.sh /bin/true

此入口点将执行在中找到的脚本 /docker-entrypoint-initdb.d 但是,正如您所注意到的,脚本也占用了空间。为了丢弃这些文件,可以使用多级构建来复制原始数据库。
再次检查dockerfile以查看图像中唯一的卷是 /var/lib/mysql . 这应该是包含数据库中所有信息的目录,它应该是您复制的内容。结果是这样的:

FROM mysql:5.7.21 as base

COPY ./init /docker-entrypoint-initdb.d
RUN docker-entrypoint.sh /bin/true

FROM mysql:5.7.21

COPY --from=base /var/lib/mysql /var/lib/mysql

尽管如此,我不建议创建“初始化”图像,因为这有点违背容器使用的精神,但这是另一个问题;)

相关问题