Memo

メモ > サーバ > 各論: Docker > データベースの永続化

■データベースの永続化
マイグレーションやシーダーで管理するとオーバーヘッドが大きくなりすぎる …という場合、データベースもファイル共有の対象にすればデータを保持できる ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう ファイル共有だと、環境によっては正しく動作しなかった ※docker-compose.ymlでrootパスワードなどを指定している場合、変更しても永続化済みのデータには影響しない つまり「何故かパスワードの変更が反映されない」となるので注意 手動でパスワードなどを変更するか、永続化済みのデータを初期化するなどする ※データベースを永続化していると、MySQLコンテナが完全に起動するまでの時間が短くなっているかも? 諸々のデータ作成が短縮できるから…かもしれない ■docker container run の場合 ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう ファイル共有だと、環境によっては正しく動作しなかった -v $PWD/docker/test/data:/var/lib/mysql を追加して起動する /var/lib/mysql を同期すれば、MySQLのデータを保持できる /docker/test/data フォルダはあらかじめ作成しておく
$ docker container run --net my_network --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7 $ docker container run --net my_network --name php -v $PWD/docker/test/code:/var/www/html -p 80:80 -d php:custom
■Docker Compose の場合 ※後述の「トラブル代替案」ように、ファイル共有ではなくデータボリュームを使う方が良さそう ファイル共有だと、環境によっては正しく動作しなかった - ./database:/var/lib/mysql を追加して起動する。意味は上と同じ compose_test\docker-compose.yml
version: '3' networks: my_network: services: mysql: container_name: mysql volumes: - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/database:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: pass MYSQL_DATABASE: test networks: - my_network image: mysql:5.7 php: container_name: php volumes: - ./:/var/www ports: - 80:80 networks: - my_network image: php:custom
■ボリュームの削除(データベースの削除)
$ docker volume ls ... ボリュームを確認 $ docker volume rm compose_mysql_data ... ボリュームを削除
■トラブル 2018/01/06 にWindowsアップデートするとDockerが起動しなくなった 再インストールで起動するようになったが、データベースの永続化ができないようになっていた Composeを使う使わないにかかわらず永続化できず、MariaDBの場合でも同じ 「-d」なしで起動すると以下のようなエラーを確認できるが、原因不明のまま解決せず Windows側で権限管理やファイルシステムの仕様が変更されたとか?
$ docker container run --name mysql -v $PWD/docker/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test mysql:5.7 Initializing database 2018-01-06T17:47:41.143661Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2018-01-06T17:47:41.150773Z 0 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive 2018-01-06T17:47:41.627330Z 0 [ERROR] InnoDB: Operating system error number 22 in a file operation. 2018-01-06T17:47:41.627674Z 0 [ERROR] InnoDB: Error number 22 means 'Invalid argument' 2018-01-06T17:47:41.628023Z 0 [ERROR] InnoDB: File ./ib_logfile101: 'aio write' returned OS error 122. Cannot continue operation 2018-01-06T17:47:41.628357Z 0 [ERROR] InnoDB: Cannot continue operation.
次の手段へ データはbusyboxに保存するのが定番らしいので試す
$ docker container run --net my_network --name storage -v /var/lib/mysql -d busybox $ docker container run --net my_network --name mysql --volumes-from storage -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7
とすればmysqlのデータをbusyboxに保存できる が、mysqlコンテナを再起動してもデータは消えないが、busyboxを再起動するとデータが消える よってbusyboxからエクスポート&インポートする必要があるが、それだとmysqlをデータ同期無しで使っている状態と変わらない 次の手段へ コンテナとローカルでデータ転送ができるらしいので試す 以下のようにすればデータ転送ができる コンテナからローカルへ
$ docker container cp mysql:/var/lib/mysql /Users/refirio/docker/backup … 絶対パスの場合 $ docker container cp mysql:/var/lib/mysql ./docker/backup … 相対パスの場合
ローカルからコンテナへ
$ docker container cp /Users/refirio/docker/backup mysql:/var/lib/mysql … 絶対パスの場合 $ docker container cp ./docker/backup mysql:/var/lib/mysql … 相対パスの場合
が、ローカルからコンテナに転送すると所有者がrootになる。chownで所有者を変更してもmysqlからは読み込めなかった 権限なども調整が必要かも 非常に面倒なので、phpMyAdminのようなツールでエクスポート&インポートする方が現実的 つまりは実質、データベースは永続化せずに作業する状態となり、かなり面倒 ■トラブル代替案 ホストの特定のパスではなく、データボリュームになら保存できた むしろ、ファイルシステムや権限の問題を回避するためにも、データボリュームを使う方がいいみたい データボリュームに保存したデータベースをバックアップしたければ、phpMyAdminなどのツールを使う dockerコマンドから起動する場合(「mysql_data」に保存)
$ docker volume ls ... ボリュームを確認 $ docker volume create --name mysql_data ... 明示的に作成できるが省略可 $ docker container run --net my_network --name mysql -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=test -d mysql:5.7 $ docker container exec -it mysql bash $ mysql -u root -p
Docker Compose から起動する場合、以下のように指定する(「compose_mysql_data」に保存する場合)
services: mysql: container_name: mysql volumes: - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf - compose_mysql_data:/var/lib/mysql
ボリュームの削除は以下のようにする
$ docker volume ls ... ボリュームを確認 $ docker volume rm compose_mysql_data ... ボリュームを削除
Dockerのデータ永続化関連について - Qiita https://qiita.com/onokatio/items/fcc9f8f94f8533bb030a dockerのデータボリュームとそのバックアップ方法 - Qiita https://qiita.com/74th/items/41393f506d223850f2c3 Docker Data Volume を理解する - Carpe Diem http://christina04.hatenablog.com/entry/2016/05/04/134323

Advertisement