LAMPプロジェクト用にDockerfileを設定しようとしていますが、MySQLの起動時にいくつか問題があります。 Dockerfileには以下の行があります。
VOLUME ["/etc/mysql", "/var/lib/mysql"]
ADD dump.sql /tmp/dump.sql
RUN /usr/bin/mysqld_safe & sleep 5s
RUN mysql -u root -e "CREATE DATABASE mydb"
RUN mysql -u root mydb < /tmp/dump.sql
しかし、私はこのエラーを受け続けます:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
Dockerfileのビルド中にデータベースの作成とダンプのインポートを設定する方法について何かアイデアはありますか?
RUN
内の各Dockerfile
命令は、異なる層で実行されます( RUN
のドキュメント で説明されているように)。
Dockerfile
には、3つのRUN
命令があります。問題は、MySQLサーバーが最初に起動されるだけであるということです。他の人はMySQLを実行していないので、mysql
クライアントとの接続エラーが発生します。
この問題を解決するには2つの解決策があります。
RUN
を使うRUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE mydb" && \
mysql -u root mydb < /tmp/dump.sql
実行可能スクリプトinit_db.sh
を作成します。
#!/bin/bash
/usr/bin/mysqld_safe --skip-grant-tables &
sleep 5
mysql -u root -e "CREATE DATABASE mydb"
mysql -u root mydb < /tmp/dump.sql
これらの行をあなたのDockerfile
に追加してください:
ADD init_db.sh /tmp/init_db.sh
RUN /tmp/init_db.sh
公式の最新版 mysql docker image は起動時にデータをインポートすることを可能にします。これが私のdocker-compose.ymlです。
data:
build: docker/data/.
mysql:
image: mysql
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: 1234
volumes:
- ./docker/data:/docker-entrypoint-initdb.d
volumes_from:
- data
ここで、私は私のdata-dump.sqlをdocker/data
の下に置いています。これはdocker-composeが実行されているフォルダからの相対パスです。そのsqlファイルをコンテナのこのディレクトリ/docker-entrypoint-initdb.d
にマウントしています。
これがどのように機能するのかを知りたい場合は、GitHubの docker-entrypoint.sh
をご覧ください。彼らはデータのインポートを許可するためにこのブロックを追加しました
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
Mysqlコンテナを停止して削除した後もデータを永続化したい場合は、docker-compose.ymlファイルにあるように別のデータコンテナを用意する必要があります。データコンテナDockerfileの内容は非常に単純です。
FROM n3ziniuka5/ubuntu-Oracle-jdk:14.04-JDK8
VOLUME /var/lib/mysql
CMD ["true"]
永続化のためにデータコンテナを開始状態にする必要すらありません。
私がしたことは "db-dump"フォルダに私のSQLダンプをダウンロードしてそれをマウントすることでした:
mysql:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: pass
ports:
- 3306:3306
volumes:
- ./db-dump:/docker-entrypoint-initdb.d
初めてdocker-compose up
を実行すると、ダンプはデータベースに復元されます。
Docker-entrypoint-initdb.dアプローチを使用しました(ありがとう@Kuhess)しかし、私の場合は、.envファイルで定義したいくつかのパラメータに基づいてDBを作成したいので、これらを行いました。
1)最初に私のdocker rootプロジェクトディレクトリにこのような.envファイルを定義します
MYSQL_DATABASE=my_db_name
MYSQL_USER=user_test
MYSQL_PASSWORD=test
MYSQL_ROOT_PASSWORD=test
MYSQL_PORT=3306
2)それではdocker-compose.ymlファイルを定義します。だから私は私の環境変数を定義するためにargsディレクティブを使い、私はそれらを.envファイルから設定しました。
version: '2'
services:
### MySQL Container
mysql:
build:
context: ./mysql
args:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
ports:
- "${MYSQL_PORT}:3306"
)それではDockerfileを含むmysqlフォルダを定義します。だからDockerfileはこれです
FROM mysql:5.7
RUN chown -R mysql:root /var/lib/mysql/
ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD
ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
ADD data.sql /etc/mysql/data.sql
RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d
EXPOSE 3306
4) mysqldumpを使って自分のデータベースをダンプし、data.sqlをmysqlフォルダの中に入れます。
mysqldump -h <server name> -u<user> -p <db name> > data.sql
このファイルは通常のSQLダンプファイルですが、先頭に2行追加して、ファイルを次のようにします。
--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;
-- Rest of queries
DROP TABLE IF EXISTS `x`;
CREATE TABLE `x` (..)
LOCK TABLES `x` WRITE;
INSERT INTO `x` VALUES ...;
...
...
...
それで何が起こっているかというと、私は "RUN sed -i/MYSQL_DATABASE/'$ MYSQL_DATABASE'/g '/etc/mysql/data.sql"コマンドを使用してMYSQL_DATABASE
プレースホルダーを自分が設定した私のDBの名前に置き換えます。 .envファイルに.
|- docker-compose.yml
|- .env
|- mysql
|- Dockerfile
|- data.sql
これでコンテナを構築して実行する準備が整いました
これはv3
のdocker-compose.yml
を使った作業バージョンです。重要なのは ボリューム ディレクティブです。
mysql:
image: mysql:5.6
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: theusername
MYSQL_PASSWORD: thepw
MYSQL_DATABASE: mydb
volumes:
- ./data:/docker-entrypoint-initdb.d
docker-compose.yml
があるディレクトリに、.sql
ダンプファイルを含むdata
ディレクトリがあります。テーブルごとに.sql
ダンプファイルを作成できるので、これはいい方法です。
私は単にdocker-compose up
を実行していますし、行ってもいいです。データは自動的に停止しても保持されます。データを削除して新しい.sql
ファイルを「吸い込む」場合は、docker-compose down
を実行してからdocker-compose up
を実行します。
ボリュームを削除せずにmysql
ドッカーが/docker-entrypoint-initdb.d
内のファイルを再処理する方法を知っている場合は、コメントを残してください。この回答を更新します。