web-dev-qa-db-ja.com

データベーススキーマを準備したdocker mysqlコンテナーの作成

私のアプリに必要なスキームがすでに含まれているmysqlの上にDockerイメージを作成したいと思います。

スキーマをSQLファイルとしてインポートする行をDockerfileに追加してみました。私はそうしました(私の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ファイル自体を直接コピーします(これは非常に厄介で、問題の汚染されたプールのように聞こえます)

助言がありますか?うまくいけば、後でメンテナンスが簡単になり、おそらくベストプラクティスにも準拠するようになるでしょうか。

17
Tom Klino

/docker-entrypoint-initdb.dとしてマウントされたディレクトリにinitスクリプトを配置する必要があります- MySQL Docker image docs の「新しいインスタンスの初期化」セクションを参照してください。

14
Greg Dubicki

テスト目的でこれを行わなければなりませんでした。

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

14
Martin Roy

@ 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

2

これが私のDockerファイルがまったく問題なく動作しているところです。/sql-scripts /には、コンテナーが実行されると実行されるカスタムsqlファイル(準備済みのdbを含む)が含まれます。ただし、ボリュームのマウントを確認することをお勧めします。

FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/
0
Rohit Salecha