Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【DockerCompose】Volumesをうまく扱う

こんばんは、葛の葉です。

前略、MySQLのデータを永続化しようと、DockerComposeのvolumesの箇所で"自分のディレクトリ:/var/lib/mysql"と記述したらMySQLがOSがどったらこったらとエラーを吐いて動きませんでした。

PCはWindows10Homeです。Docker上でMySQLを動かすと、動かしているときはLinuxだけど、保存先がwinになってる。MySQLコンテナは困惑して轟沈した、というわけのようです。

そもそもデータを永続化出来ればいいのであって、windowsにマウントする必要はないです。コンテナを落としても、新たにコンテナが立ち上がった時に同じデータを引き継いでくれればそれで良いです。

というわけで、コンテナのデータをDocker内のvolumeにマウントさせるということをやっていこうかなぁと思います。

とても参考になったサイト

qiita.com

Version

Docker Toolboxを使用しています。

# docker version
Client:
 Version:       18.03.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0520e24302
 Built: Fri Mar 23 08:31:36 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm
Server: Docker Engine - Community
 Engine:
  Version:      18.09.2
  API version:  1.39 (minimum version 1.12)
  Go version:   go1.10.6
  Git commit:   6247962
  Built:        Sun Feb 10 04:20:28 2019
  OS/Arch:      linux/amd64
  Experimental: false

# docker-compose version
docker-compose version 1.20.1, build 5d8c71b2
docker-py version: 3.1.4
CPython version: 3.6.4
OpenSSL version: OpenSSL 1.0.2k  26 Jan 2017

docker-compose.ymlではこんな感じ。

今回はMySQLとRedisもやってみた。

version: "3"
services:
    mysql-svc:
        image: mysql:5.7.25
        environment:
            MYSQL_DATABASE: db
            MYSQL_ROOT_PASSWORD: secret
            TZ: "Asia/Tokyo"
        volumes:
            - "mysql_data:/var/lib/mysql"

    redis-svc:
        image: redis:5.0.3
        environment:
            TZ: "Asia/Tokyo"
        volumes:
            - "redis_data:/data"

volumes:
    mysql_data:
    redis_data:

servicesと同じレベルにvolumesというものが書かれています。これはDockerComposeを通じてvolumeというものを作成します。

volumeの機能自体はDockerComposeのものではなくDockerの機能です。また、複数のオプションが存在しています。色々と調べてみてくださいな。

docker-compose up -dとすれば以下のようになります。

$ docker-compose up -d
Creating network "docker_test_default" with the default driver
Creating volume "docker_test_mysql_data" with default driver
Creating volume "docker_test_redis_data" with default driver
Creating docker_test_mysql-svc_1 ... done
Creating docker_test_redis-svc_1 ... done

docker_testっていうディレクトリ上で起動しているのでプレフィックスがこうなってます。

MySQLにデータを入れる

mysql-svcサービスでmysqlクライアントを起動してみます。

docker-compose exec mysql-svc mysql -p

パスワードはsecretです。

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.25 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

use db;としてdbを移動し、適当にhogehogeテーブルでもつくり、適当に値を入れます。ちなみになんでdbっていうデータベースが存在しているかというと、Dockerのmysqlイメージがコンテナを生成するときに、そのコンテナがMYSQL_DATABASEという環境変数の値の名前のデータベースを作成するからです。

CREATE TABLE hogehoge (id int, name varchar(40), price int);

INSERT INTO hogehoge VALUES(1, "LION", 200);

INSERT INTO hogehoge VALUES(2, "BAER", 180);

SELECT * FROM hogehoge;とすればテーブルが表示されます。

+------+------+-------+
| id   | name | price |
+------+------+-------+
|    1 | LION |   200 |
|    2 | BAER |   180 |
+------+------+-------+
2 rows in set (0.00 sec)

次回コンテナ起動時にこのデータを見ることが出来ればよいわけですね。

MySQLのコンテナを再起動してデータを確認する

docker-compose downとして、コンテナが落ちることを確認します。

$ docker-compose down
Stopping docker_test_mysql-svc_1 ... done
Stopping docker_test_redis-svc_1 ... done
Removing docker_test_mysql-svc_1 ... done
Removing docker_test_redis-svc_1 ... done
Removing network docker_test_default

volumeが削除されていないという点をよくみておきましょう。そうしましたらもう一度立ち上げます。

$ docker-compose up -d
Creating network "docker_test_default" with the default driver
Creating docker_test_mysql-svc_1 ... done
Creating docker_test_redis-svc_1 ... done

前回と比べてvolumeが作成されていない点をよくみておきましょう。

$ docker-compose exec mysql-svc mysql -p
Enter password: 

mysql> use db;
Database changed

mysql> select * from hogehoge;
+------+------+-------+
| id   | name | price |
+------+------+-------+
|    1 | LION |   200 |
|    2 | BAER |   180 |
+------+------+-------+
2 rows in set (0.00 sec)

出ましたね。ちなみにRedisでも同じように確認することが出来ました。

お片付け

docker-compose downしてもvolumeが消えませんでした。実は次のコマンドを打つことでvolumeも一緒に削除することが出来ます。

docker-compose down -v
$ docker-compose down -v
Stopping docker_test_mysql-svc_1 ... done
Stopping docker_test_redis-svc_1 ... done
Removing docker_test_mysql-svc_1 ... done
Removing docker_test_redis-svc_1 ... done
Removing network docker_test_default
Removing volume docker_test_mysql_data
Removing volume docker_test_redis_data