当前位置: 首页 > 知识库问答 >
问题:

我应该如何为开发数据库构建docker映像?

翟奇逸
2023-03-14

我有一个开发数据库,我想在docker映像中提交该数据库,将其推送到一个私有存储库,并在本地开发和CI构建中使用。

数据库保存为SQL备份,通过将备份文件映射到官方映像的/docker entrypoint initdb,我可以成功地将其恢复到MariaDB容器中。d/目录,它将在第一次运行容器时执行此备份文件。发生这种情况时,MariaDB会将数据库还原到容器/var/lib/mysql中的数据文件中。

理论上,我可以停止容器,将其提交给一个新图像,推动它,然后我就完成了。然而,MariaDB的Dockerfile声明了VOLUME /var/lib/mysql,这意味着一旦容器被创建,该路径将被映射到主机上的自动命名卷,即使-卷没有用于显式挂载在那条小路上。由于路径是从主机挂载的,还原的数据库将不会被docker提交捕获。似乎无法覆盖此自动卷挂载。

一种解决方法是docker创建一个新容器而不运行它,docker cpmy数据库备份到/docker entrypoint initdb。d/,然后docker将其提交到新映像。可以推送此映像,因为它包含备份数据,并且在第一次运行时,MariaDB会将其恢复到数据库中。但是,无论何时创建容器,您都必须等待恢复完成,而不是与已恢复的数据库一起提供的映像。

另一种解决方法是分叉MariaDB Dockerfile以删除VOLUME指令,或者通过在基本映像上自行安装MariaDB来创建自己的指令。

第三种选择可能是创建我自己的Dockerfile以从mariadb构建为基础映像,并尝试在构建过程中进行恢复,但我尚未对此进行全面研究。

实现这一目标最有效的方法是什么?


共有1个答案

微生良策
2023-03-14
匿名用户

我找到了以下方法:

卷定义存储在图像元数据中,因此可以手动更改此元数据,以删除VOLUME声明并将结果保存到新图像中。这个过程已经封装在一个名为docker-copyedit的有用的Python包中。

$ docker pull mariadb
$ pip install docker-copyedit
$ docker-copyedit.py FROM mariadb INTO mariadb:novolumes REMOVE ALL VOLUMES

现在,我有了MariaDB的本地: novoluel映像,我可以在Dockerfile构建中自动化数据库。为了使用映像的内置功能来创建一个新的数据库并从/docker-entrypoint-initdb. d/目录进行恢复,我创建了一个bash脚本,它提供docker-entrypoint.sh的源,然后执行<代码>_main()执行还原,然后退出,而不直接执行_main()(这将导致重新启动数据库,以便构建永远不会退出)。然后我使用第二个构建阶段从还原阶段导入/var/lib/mysql目录。

FROM mariadb:novolumes AS restorer

ENV MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes

COPY data/source/database.sql /docker-entrypoint-initdb.d/

COPY restore_db.sh restore_db.sh
RUN ["./restore_db.sh", "mysqld"]

FROM mariadb:novolumes

COPY --from=restorer /var/lib/mysql /var/lib/mysql
#!/bin/bash

# Import helper functions
source docker-entrypoint.sh

# Direct copy-paste of lines 356-392 from docker-entrypoint.sh:

mysql_note "Entrypoint script for MariaDB Server ${MARIADB_VERSION} started."

mysql_check_config "$@"
# Load various environment variables
docker_setup_env "$@"
docker_create_db_directories

# If container is started as root user, restart as dedicated mysql user
if [ "$(id -u)" = "0" ]; then
  mysql_note "Switching to dedicated user 'mysql'"
  exec gosu mysql "$BASH_SOURCE" "$@"
fi

# there's no database, so it needs to be initialized
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
  docker_verify_minimum_env

  # check dir permissions to reduce likelihood of half-initialized database
  ls /docker-entrypoint-initdb.d/ > /dev/null

  docker_init_database_dir "$@"

  mysql_note "Starting temporary server"
  docker_temp_server_start "$@"
  mysql_note "Temporary server started."

  docker_setup_db
  docker_process_init_files /docker-entrypoint-initdb.d/*

  mysql_note "Stopping temporary server"
  docker_temp_server_stop
  mysql_note "Temporary server stopped"

  echo
  mysql_note "MariaDB init process done. Ready for start up."
  echo
fi

最后,我可以构建并运行容器来快速创建本地开发数据库,和/或将映像推送到存储库。

$ docker build -t NReilingh/devdb .
$ docker run --rm -d NReilingh/devdb

 类似资料:
  • 问题内容: 我对应用程序进行了docker化处理,但是要查看我的更改,我必须重建图像,并且不能为我提供应用程序的实时预览。 因此,我创建了一个docker- compose环境,该环境将redis链接到我的节点容器,然后将源代码从主机挂载到节点应用程序并监视其更改。但是,由于代码不是UnionFS的一部分,因此无法进行容器化。 如何设置一个开发环境,该环境可以生成dockerized映像,但是每次

  • 问题内容: 我正在尝试 使用 官方链接中提到 的API 构建 docker镜像 。 但是我无法获得文件中的内容:示例请求: 有几件事使我感到困惑, 1)在哪里提到 Dockerfile 的 路径 ? 2)“归档文件必须在归档文件的根目录中包含一个构建指令文件,通常称为Dockerfile。” 来自docker docs的此声明,这里的困惑 是存档的根 是 什么 ? 3) 构建图像的详细命令 是什么

  • 问题内容: 在为数据库(例如MySQL)设计模式时,会出现一个问题,即是否要完全规范化表。 一方面,联接(以及外键约束等)非常慢,另一方面,您会获得冗余数据和潜在的不一致情况。 这里“最优化”是正确的方法吗?即创建一个书本归一化数据库,然后查看可以进行归一化以实现最佳速度增益的内容。 对于这种方法,我的担心是,我将选择一个可能不够快的数据库设计- 但是在那个阶段重构模式(同时支持现有数据)将非常痛

  • 目前,我发现谷歌云构建发生在构建docker图像的时候(不像我想象的那样,它会构建我的图像,然后执行我的图像来完成所有的构建)。那是在这篇文章里 谷歌云构建的快速启动 我有一个Dockerfile现在很简单 我有一个单一的下载和提取下载任何工件(zip文件)从最后的单构建运行构建(只有修改的服务器被构建或依赖于上一个CI构建的变化的服务器被构建,就像下游库可能被更改)。第一行只是列出了我需要在一个

  • 问题内容: 有人可以为我指出一份良好的初学者指南,以安全地运行部分由用户输入构成的SQL查询吗?我正在使用Java,但是语言无关的指南也很好。 期望的行为是,如果有人在GUI中键入类似 数据库应将其视为文字字符串,并安全地存储它而不会删除任何表。 问题答案: 您肯定要使用PreparedStatement。他们很方便。这是一个例子。