使用 mysql 的 Docker 镜像,您可以将 mysqldump 脚本放入特定文件夹,它将使用这些脚本在首次启动时加载空数据。
我想知道如何创建一个图像,其中该执行已经作为构建的一部分进行,这样我们就不必等待初始数据加载。
该图像的目的是为了让开发人员拥有数据库的副本以供本地测试。
如果可能的话,我希望将其作为多阶段 Docker 构建来完成,这样我就可以在不安装 MySQL 的情况下在构建服务器上进行构建。
尽管我还没有尝试过,但我的总体思维过程如下:
FROM mysql as builder
COPY *.sql /somefolder
COPY buildscript.sh /buildscript.sh
FROM mysql
COPY --from build /var/lib/mysql /data # to avoid using the volume folder
并buildscript.sh
做一些类似的事情
- 启动 mysqld
- 等待 mysqld 完全启动(??)
- 运行用于构建数据的 SQL
- 关闭 mysqld
- 同步(确保所有文件都已写入)
答案1
我认为可以在 Dockerfile 中执行此操作,而不是在入口点执行操作。您应该将数据库数据复制到映像中,并配置 my.cnf 以指向存储该数据的目录,并跳过将转储操作转到入口点。无论如何,作为个人考虑,您从中获得了哪些好处?我的意思是,是的,您不必等待在运行时创建和填充数据库,但是每次重新构建映像时都会花费您的时间,并且由于其中包含一些数据,因此映像也会变得更大。您必须考虑是否计划重新构建大量映像,这不会在时间成本上发生太大变化,如果您不打算频繁重新构建映像,这可能是一个优势。
答案2
这是我当前的工作解决方案。
我先从Dockerfile
FROM mysql:5.7.23 as prep
COPY *.sql /docker-entrypoint-initdb.d/
COPY scripts/build-db.sh /
ARG MYSQL_ROOT_PASSWORD=my-very-secret
ARG MYSQL_USER=sampleuser
ARG MYSQL_PASSWORD=password123
RUN chmod u+x /build-db.sh
RUN /build-db.sh
FROM mysql:5.7.23
# use /data in my case so that it uses a directory that is not a VOLUME
COPY --from=prep /data /data
然后我添加一个build-db.sh
设置现有的入口点并删除最后exec
一行,使其在完成初始化后停止。之所以放入数据,是/data
因为默认情况/var/lib/mysql
下构建的下一阶段不会包含任何数据。
#!/bin/bash
head -n -1 /usr/local/bin/docker-entrypoint.sh > /d2.sh
chmod +x /d2.sh
exec /d2.sh --datadir=/data
要启动它,您需要--datadir=/data
使用非卷目录。