Webアプリケーションの環境構築する場合、データベースのコンテナとしてはMySQLのイメージを使う事があります。
MySQLのイメージからコンテナを作る場合、docker-compose.yml
のenviroment
を設定すれば、データベースとアカウントを初期投入する事が出来ます。
例えば下記のように指定した場合、test
というデータベースと、user
というアカウントが作成されます。
version: '3.7' services: db: build: ./docker/db environment: MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: pass MYSQL_USER: user MYSQL_PASSWORD: psss ports: - 3306:3306
ただ、一度構築したあと、enviroment
を更新してdocker-compose build
を実行しても、データベースを作り直す事が出来ません。
キャッシュを使わないオプション(--no-cache
)を使用しても、解決しません。
さて、
今回は初期投入データを変更して、コンテナに適用する方法についてです。
ビルドすると作られるデータ
docker-compose.ymlを設置して、docker-compose build
を実行すると次の情報が追加されます。
- image
- container
- network
- volume
今回、特筆すべきなのはvolumeです。
volumeについて
コンテナとは別に、ストレージのようにデータを管理する事が出来ます。
volume(以下、ボリューム)で管理する事で、永続的にデータを管理する事が可能になります。
永続化する事、コンテナと別に管理する事が出来ます。
コンテナとボリュームとの紐付けが出来ていれば、コンテナを消してもボリュームはそのまま移行する事ができるようになります。
MySQLのイメージの場合
公式ページのCaveatsのWhere to Store Dataには、次のように書かれています。
Let Docker manage the storage of your database data by writing the database files to disk on the host system using its own internal volume management. This is the default and is easy and fairly transparent to the user. The downside is that the files may be hard to locate for tools and applications that run directly on the host system, i.e. outside containers.
MySQLで扱うデータはボリュームで管理しています。
そのため、コンテナを削除してもボリュームが残り、データベースの初期化がされません。
変更方法
該当するボリュームが残っているため、新しくデータベースを構築しません。
そのため、ボリュームを削除してからビルドし直します。
注意
ボリュームを削除すると、データベースのデータが消えます。
もし、残しておきたいデータがある場合は、バックアップを取ってください。
手順
STEP.1 コンテナ削除
docker-compose
で作成したコンテナを削除します
$ cd (docker-compose.ymlがある場所) $ docker-compose down # ボリュームに関連するコンテナを削除
STEP.2 該当ボリューム削除
コンテナに紐づくボリュームを削除します。
docker-composeにはボリュームを削除するオプションが無いようです。
docker volume
で該当するボリュームを探して削除します。
$ docker volume ls DRIVER VOLUME NAME local (MySQLのコンテナ名)-data $ docker volume rm (MySQLのコンテナ名)-data (MySQLのコンテナ名)-data
STEP.3 コンテナ再構築
MySQLの初期データが消えたので、docker-compose.yml
を更新してビルドすれば新しい設定値でデータベースを作り直します。
$ docker-compose build
Tips
Dockerで管理するデータを全て削除する
冒頭で記述した、下記のデータを(プロジェクトに関係なく)全て削除する方法です。
- image
- container
- network
- volume
$ docker stop $(docker ps -aq) $ docker rm $(docker ps -aq) $ docker network prune -f $ docker rmi -f $(docker images --filter dangling=true -qa) $ docker volume rm $(docker volume ls --filter dangling=true -q) $ docker rmi -f $(docker images -qa)