2015-09-09 145 views
15

我想创建一个已经填充数据的MySQL Docker镜像。如何在构建时创建已填充的MySQL Docker镜像

我要创建3层是这样的:

 |---------------------|---------------------| 
Layer 3 | Customer 1 Database | Customer 2 Database | 
     |---------------------|---------------------| 
Layer 2 | Database image with tables but no data | 
     |-------------------------------------------| 
Layer 1 |    mysql:5.6.26    | 
     |-------------------------------------------| 

我的问题是现在如何为第2层和3创建一个正确Dockerfile? 其中我的empty_with_tables.sql文件被加载到第2层,customer1.sql和customer2.sql被加载到第3层的两个图像中。我读了一些关于将SQL文件放入'/docker-entrypoint-initdb.d'的内容。但这会导致数据在图像首次启动时出现。这不是我想要的。我希望数据能够在图像中准备好(例如在测试中快速提供)。

我可以启动mysql映像,从命令行加载数据并执行“提交”,但这不是可重复的,需要在SQL文件中的数据更改时重新执行。

这怎么办?

最好的问候,

  • 莫滕绿满森

回答

3

所以我对这个问题的解决方案只是不分层,而是创建一个基本映像,并使用--volumes-from从数据专用容器注入数据库文件。

+4

您能否提供更多信息?我也想这样做。 – Telokis

+1

@Morten Green请花时间分享您的工作,我们在这里互相帮助。 – Dung

4

这无法完全做到你想要的确切方式,来,官方mysql形象立足的时候,因为你需要沟通至少服务器导入数据和服务器不运行并初始化(从mysql的docker-entrypoint.sh),直到容器运行,这是只有当图像已经建立。

不那么干净的方法是在容器中运行的过程中,利用从MySQL形象/entrypoint.sh脚本,但你必须采取的(如$MYSQL_ROOT_PASSWORD)的入口点所需的所有设置以及清洁护理在导入数据后立即停止守护进程。喜欢的东西:

FROM mysql:5.6 

ADD data.sql /docker-entrypoint-initdb.d/00-import-data.sql 
ENV MYSQL_ROOT_PASSWORD somepassword 
ENV MYSQL_DATABASE db1 
RUN /entrypoint.sh mysqld & sleep 30 && killall mysqld 

是导致预初始化DB一个hackish的方式,但是......这是行不通的。原因是/var/lib/mysql在mysql的Dockerfile中声明为一个卷,并且在构建过程中对该目录所做的任何更改在构建步骤完成后都会丢失。这可以通过以下Dockerfile观察:

FROM mysql:5.6 

RUN touch /var/lib/mysql/some-file && ls /var/lib/mysql 
RUN touch /var/lib/mysql/some-file2 && ls /var/lib/mysql 

所以我建议你描述docker commit方式去。最终结果与您想要实现的结果相同,但第2层也许是例外。

UPDATE:由于OP评论如下,提交也不包含卷。所以,唯一的办法似乎是编辑MySQL Dockerfile并删除VOLUME以将数据保留在容器中,或者独立于容器管理卷。

+1

您好!对于迟到的答案我很抱歉! 提交方法没有问题吗?在官方Dockerfile中定义了一个卷('VOLUME/var/lib/mysql'),这就是数据库所在的位置。因此,一个提交将不包括这些文件在一个新的形象(我做了'码头差异'检查)。我能不能'卸货'坐骑? –

+0

你是对的;这是卷对任何提交都不透明的普遍问题(因此在构建期间它不起作用)。请参阅https://github.com/docker/docker/issues/6999。人们通常克隆原始回购,并在自定义修改后移动VOLUME,或将其一并移除 - 请参阅https://github.com/stuartpb/rethinkdb-dockerfiles/issues/14 – pwes

15

本周我遇到了同样的问题。我发现,无需工作的解决方案--volumes-from

这已经指出的是,/var/lib/mysql是音量,由于码头工人是不会支持UNVOLUME在它Dockerfile在不久的将来出现问题,则不能使用这个位置适用于您的数据库存储,如果您想从默认的空数据库开始。 (https://github.com/docker/docker/issues/18287)。这就是为什么我覆盖etc/mysqld.my.cnf,给mysql一个新的datadir。

用的PWE他的回答

在一起,你可以这样创建一个Dockerile:

FROM mysql:5.6 

ENV MYSQL_DATABASE db 
ENV MYSQL_ROOT_PASSWORD pass 
COPY db.sql /docker-entrypoint-initdb.d/db.sql 
COPY my.cnf /etc/mysql/my.cnf 
RUN /entrypoint.sh mysqld & sleep 30 && killall mysqld 
RUN rm /docker-entrypoint-initdb.d/db.sql 

存在my.cnf唯一的变化是datadir的位置:上MegaWubs的

.... 
[mysqld] 
skip-host-cache 
skip-name-resolve 
user  = mysql 
pid-file = /var/run/mysqld/mysqld.pid 
socket  = /var/run/mysqld/mysqld.sock 
port  = 3306 
basedir  = /usr 
datadir  = /var/lib/mysql2 <-- can be anything except /var/lib/mysql 
tmpdir  = /tmp 
lc-messages-dir = /usr/share/mysql 
explicit_defaults_for_timestamp 
.... 
+0

干净的工作细节MW – Drew

4

大厦回答,我发现这个Dockerfile已经足够了。

FROM mysql:5.6 
RUN sed -i 's|/var/lib/mysql|/var/lib/mysql2|g' /etc/mysql/my.cnf 
+1

使用mysql:5.7,我使用: '''运行sed -i'|/var/lib/mysql |/var/lib/mysql2 | g'/ etc/mysql/mysql。 conf.d/mysqld.cnf''' –

相关问题