2015-09-09 144 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''' –

相關問題