Docker Composeのトップレベルvolumesでホストのディレクトリをマウントする

composeファイルのバージョン2以降で、YAMLのトップレベルにvolumes:を置いてボリュームの定義をし、service:内でそのボリューム名を指定するという書き方ができます。

version: "2"
services:
  database:
    image: mariadb:10
    volumes:
      - datastore:/var/lib/mysql
...(略)...
volumes:
  datastore:

Docker EngineやDocker Composeのドキュメントを見るとこんな感じで書いてあるかと思います。この書き方だとdatastoreはlocalというドライバを使用して/var/lib/docker/volumes/datastore/_dataあたりのディレクトリをコンテナ内にマウントするという動作になります。

消えちゃう問題

この方式は各サービスのvolume:ではホスト側はボリュームの名称を指定するのでいちいちディレクトリパスを書かずに済むのですが、dockerコマンドでボリュームを削除するとホスト側のディレクトリごと削除されてしまうので、うっかりdocker system pruneとかしちゃうとデータベースのデータまで丸ごと消えてしまうといった事案が発生してしまいます。

サービス内で毎回ホスト側のディレクトリパスを指定する書き方ならマウントが解除されるだけで、ホスト側のディレクトリやファイルまでは消えないんですけどね…

マウントだけにする方法

Docker EngineやDocker Composeのドキュメントで見つけることができずマウントのみにする方法はないもんだと思っていたのですが、偶然こんなIssueを見る機会がありまして、こんなコメントがありました。

docker volume create --opt type=none --opt device=<host path> --opt o=bind

さらにはそれをcomposeファイルにしたものが。

volumes:
  database:
    driver_opts:
      type: none
      device: /path/is/writable/dir-does-not-exist/
      o: bind

type: noneってなんなのよ… と思いつつまねしてみたら

version: "2"
services:
  database:
    image: mariadb:10
    volumes:
      - datastore:/var/lib/mysql
...(略)...
volumes:
  datastore:
    driver_opts:
      type: none
      device: /home/docker/data/mariadb
      o: bind

2017/04/28 18:06追記)

driver_ops:が抜けていたので修正しました。

docker-compose downしてdocker system pruneしても/home/docker/data/mairadbやその中のファイルは生き残ってます! これは嬉しい! 以上です。

しかし、これドキュメントのどこに書いてあるんだろう…

2017/04/24 08:38
タグ: