2015-09-09 11 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の2つのイメージにロードされます。私はSQLファイルを '/docker-entrypoint-initdb.d'に置くことについて何かを読んでいます。しかし、これは、画像が最初に開始されるときのデータをもたらす。これは私が望むものではありません。私は、データが画像の中に用意されていることを望んでいます(例えば、テストですぐに利用できるように)。

私はmysqlイメージを起動し、コマンドラインからデータをロードして 'コミット'することができますが、これは再現性がなく、SQLファイルのデータが変更されたときに再実行する必要があります。

どうすればいいですか?

敬具、

  • モーテン・グリーンHermansenの

答えて

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になりハック方法ですが、...それは動作しません。その理由は、/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')。これはデータベースが置かれている場所です。したがって、コミットはそれらのファイルを新しい画像に含めません(私は 'docker diff 'でチェックしました)。そして私はマウントを解除することはできませんか? –

+0

あなたは正しいです。これは、ボリュームがどのコミットに対しても不透明である一般的な問題です(したがって、ビルド中には動作しません)。 https://github.com/docker/docker/issues/6999を参照してください。一般的にオリジナルのリポジトリをクローンし、カスタム修正後にVOLUMEを移動するか、すべて削除します - https://github.com/stuartpb/rethinkdb-dockerfiles/issues/14 – pwes

15

今週も同じ問題が発生しました。私は--volumes-from

すでに/var/lib/mysqlが近い将来にDockerfileのボリュームで、ドッカーので中UNVOLUMEをサポートするつもりはないということです述べています問題を必要とせずに作業溶液を見つけた、あなたが使用することはできませんデフォルトでは空のデータベースを使い始める場合は、データベースストレージのこの場所を使用します。 (https://github.com/docker/docker/issues/18287)。だから私はetc/mysqld.my.cnfを上書きし、mysqlに新しいdatadirを与えます。 pwes'彼の答えと一緒に

、あなたはこのようにDockerileを作成することができます。

.... 
[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

ビルMegaWubsのオン:

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の場所であります答え、私はこの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''' –