使用准备好的数据库方案创建docker mysql容器


17

我想在mysql映像之上创建一个docker映像,该映像已经包含我的应用程序所需的方案。

我尝试向Dockerfile添加行,这些行会将我的方案导入为sql文件。我是这样做的(我的Dockerfile):

FROM mysql

ENV MYSQL_ROOT_PASSWORD="bagabu"
ENV MYSQL_DATABASE="imhere"

ADD imhere.sql /tmp/imhere.sql

RUN "mysql -u root --password="bagabu" imhere < /tmp/imhere.sql"

据我了解,这是行不通的,因为mysql docker映像不包含mysql客户端(最佳做法是“不要仅仅因为它们会很舒服就添加东西”)(我对此是否错?)

这样做的好方法可能是什么?我已经想到了一些事情,但是它们似乎都是混乱的解决方法。

  1. 安装mysql客户端,做我必须做的事,然后删除/清除它。
  2. 将mysql客户端二进制文件复制到该映像,执行我必须做的,然后将其删除。
  3. 在另一台sql服务器中创建架构,然后直接直接复制db文件(这看起来很混乱,在我看来像是受污染的问题池)

有什么建议么?希望以一种易于稍后维护并且也可能符合最佳实践的方式吗?


Answers:


14

您应该将init脚本放在安装为的目录中/docker-entrypoint-initdb.d-请参阅MySQL Docker图像文档中的“初始化新实例”部分。


2
这可以调出一个新的容器并将其加载到我的架构中。这是一个很好的解决方法,但是如果我正在寻找一种方法来创建自己的已经预先安装了架构的Docker映像,该怎么办?
汤姆·克利诺

其实,没关系:-)我以为/docker-entrypoint-initdb.d是在主机中,但实际上是在容器中。我将ADD命令更改为复制到该目录,并删除了该RUN命令。Docker成功构建了映像,我对其进行了测试,并且可以正常工作。
汤姆·克利诺

14

我出于测试目的必须这样做。

这是我通过利用dockerhub上的实际MySQL / MariaDB映像和多阶段构建来进行的操作:

FROM mariadb:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"]

FROM mariadb:latest

COPY --from=builder /initialized-db /var/lib/mysql

完整的工作示例在这里:https : //github.com/lindycoder/prepopulated-mysql-container-example


2
我在整个互联网上找到的最佳答案,我的是Postgres,所以有点困难,但终于可以了。而且效果很好!
snowe2010 '18

较早版本的mysql(5.7.9)没有将/usr/local/bin/docker-entrypoint.sh符号链接到/entrypoint.sh,而在/中仅包含entrypoint.sh。将/usr/local/bin/docker-entrypoint.sh更改为/entrypoint.sh是可行的,并且大概也应该适用于“现代”发行版。
Marvin

2

归功于@Martin Roy

进行了较小的更改以适用于mysql ...

内容Dockerfile

FROM mysql:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db"]

FROM mysql:latest

COPY --from=builder /initialized-db /var/lib/mysql

内容setup.sql

CREATE DATABASE myexample;

USE myexample;

CREATE TABLE mytable (myfield VARCHAR(20));

INSERT INTO mytable VALUES ('Hello'), ('Dolly');

完整的工作示例在这里:https : //github.com/iamdvr/prepopulated-mysql-container-example


-1

像Ansible这样的管理软件可以帮助您轻松地自动执行mysql导入,而无需安装和重新安装客户端。Ansible具有强大的内置功能来管理Docker映像和容器以及mysql数据库。


很有意思-我使用了Ansible,但还没有将其用于Docker映像。帕特里克,您可以列举一些例子来扩展答案吗?
格雷格·杜比奇

Ansible的文档页面很棒,您可以在以下URL上找到Ansible模块:docs.ansible.com/ansible/docker_module.html 本指南模块一章的每个页面上都有一些示例。
Patrick
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.