私のアプリに必要なスキームがすでに含まれている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クライアントが含まれていないため、これは機能しませんでした(ベストプラクティスは、「持っているのがいいからといって、追加しないでください」)(これについて間違っていますか?)
これを行うための良い方法は何でしょうか?私はいくつかのことを念頭に置いていましたが、それらはすべて厄介な回避策のように見えます。
助言がありますか?うまくいけば、後でメンテナンスが簡単になり、おそらくベストプラクティスにも準拠するようになるでしょうか。
/docker-entrypoint-initdb.d
としてマウントされたディレクトリにinitスクリプトを配置する必要があります- MySQL Docker image docs の「新しいインスタンスの初期化」セクションを参照してください。
テスト目的でこれを行わなければなりませんでした。
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
@ 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
これが私のDockerファイルがまったく問題なく動作しているところです。/sql-scripts /には、コンテナーが実行されると実行されるカスタムsqlファイル(準備済みのdbを含む)が含まれます。ただし、ボリュームのマウントを確認することをお勧めします。
FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/