0

我有一个网站,其中包含与大型、不变的 MySQL 数据库相关联的非常具体的 JS 代码。我希望能够将网站和数据库作为单个包分发,以便其他人能够在本地运行,所以我一直在研究使用 docker 来做这件事。请注意,我没有使用 docker 来测试正在运行的应用程序:只是为了将其分发给其他人查看。

据我了解,运行已填充 MySQL 数据库的 docker 映像通常.sql在启动数据库后从文件中加载它。但是,对于我的数据库内容,这会导致一个小时的等待来填充数据库,因为 .sql 转储有很多 GB,并且需要很长时间才能加载。因此,我正在考虑将数据加载到正在运行的数据库中一次,将数据库卷( )保持在图像本地,并在加载数据后/var/lib/mysql使用创建图像的快照。docker commit

然而,这种方法似乎违背了许多标准docker commit的 docker 建议:通常不受欢迎,并且/var/lib/mysql存储为单独的数据卷,而不是保存在图像本身中。尽管如此,我的用例似乎有所不同,因为 (a) 数据库中的数据不打算在未来更改 (b) 从 mysql 转储加载需要很长时间以及 (c) 大型数据存储(而不是不仅仅是 js 应用程序代码)是我真正想要包含在图像中的主要内容之一。

那么我的用例是否是打破约定并docker commit与将 MySQL 文件保存在映像本身而不是单独的数据卷一起使用的正当理由?或者有没有一种替代的、更标准的方式来分发一个完全工作、完全填充的 web 应用程序和一个大型固定数据库存储?

4

1 回答 1

0

我发现docker commit你可以使用多阶段构建而不是使用。在构建的早期阶段,RUN可以使用命令来填充数据库(例如,在 中创建数据库文件/var/lib/mysql)。如果/var/lib/mysql是数据卷,则作为构建的最后阶段,/var/lib/mysql可以将整个目录复制到永久的非数据卷位置,例如/var/lib/mysql_permanent,使用 eg

ENV MYSQL_DATA_DIR=/var/lib/mysql_permanent
# copy the DB files from the previous image
COPY --from=create_database "/var/lib/mysql" "${MYSQL_DATA_DIR}"

然后将使用烘焙到图像中的正确基础数据库文件创建最终图像。然后,最后一个构建阶段需要mysqld使用 mysqld.cnf 文件来运行该过程datadir=${MYSQL_DATA_DIR},以访问正确的文件。然后,这绕过了对 的需求docker commit,并在构建阶段完成了所有工作。

于 2021-05-05T09:03:35.867 回答