現在の仕事では各個人の開発環境をDockerで用意しています。基本的にコードがあるディレクトリをコンテナ側と共有していますが、一部分だけ共有したくないというケースが発生しました。以下のようなケースです。
drwxr-xr-x 571 denzow staff 19414 3 18 09:43 node_modules -rw-r--r-- 1 denzow staff 286 3 18 09:43 package.json drwxr-xr-x 3 denzow staff 102 3 18 09:47 src -rw-r--r-- 1 denzow staff 584 3 18 09:47 webpack.config.js -rw-r--r-- 1 denzow staff 134 3 18 09:51 Dockerfile_webpack -rw-r--r-- 1 denzow staff 205 3 18 09:52 docker-compose.yml
src
配下のファイルをdist
にビルドするwebpackを導入したコンテナを構成しています。このディレクトリをコンテナと共有しますが、ホスト側がMacでコンテナ内がLinuxですのでnode_modules
はできれば共有したくありません。カレントは共有する、ただしnode_modulesを除くという状況の実現方法を調べました。
本例詳細
関連ファイルの現時点での内容は以下です。
- Dockerfile_webpack
FROM node:7.1.0 WORKDIR /app COPY ./package.json package.json RUN npm install
- docker-compose.yml
version: '3.0' services: webpack: build: context: . dockerfile: Dockerfile_webpack restart: always command: 'node node_modules/.bin/webpack --watch' volumes: - .:/app
volumes
の指定にあるように、ホスト側の.
をコンテナ内の/app
にマウントしています。ここから./node_modules
を除外していきます。 現時点では以下のように共有されてしまっています。
-- ホスト側でファイル作成 denzownoMacBook-Pro:submount denzow$ touch node_modules/test -- コンテナ側からもファイルが見えている denzownoMacBook-Pro:submount denzow$ docker exec submount_webpack_1 ls -l node_modules/test -rw-r--r-- 1 root root 0 Mar 18 01:08 node_modules/test
どうするのか
このStackoverflowが参考になりましした。
端的に言えば、volumeを作ってホスト側と共有したくないディレクトリに重ねるというものです。docker-compose.yml
を以下のように変更します。
version: '3.0' services: webpack: build: context: . dockerfile: Dockerfile_webpack restart: always command: 'node node_modules/.bin/webpack --watch' volumes: - .:/app + - node_modules:/app/node_modules + + volumes: + node_modules: + driver: 'local'
以下の部分でData Volume
を作成しています。
volumes: node_modules: driver: 'local'
そして、ここで作成したData Volume
をwebpack
コンテナの/app/node_modules
にマウントしています。これでコンテナの/app/node_modules
はホストの<base_dir>/node_modules
と分けることができます。
実際に確認すると以下のように共有されていないことがわかります。
-- ホスト側でファイル作成 denzownoMacBook-Pro:submount denzow$ touch node_modules/test -- コンテナからは見えていない denzownoMacBook-Pro:submount denzow$ docker exec submount_webpack_1 ls -l node_modules/test ls: cannot access node_modules/test: No such file or directory
docker inspect
でも別のディレクトリになっていることがわかります。
denzownoMacBook-Pro:submount denzow$ docker inspect submount_webpack_1 : "Mounts": [ { "Type": "bind", "Source": "/Users/denzow/work/docker_test/submount", "Destination": "/app", "Mode": "rw", "RW": true, "Propagation": "rprivate" }, { "Type": "volume", "Name": "submount_node_modules", "Source": "/var/lib/docker/volumes/submount_node_modules/_data", "Destination": "/app/node_modules", "Driver": "local", "Mode": "rw", "RW": true, "Propagation": "" } ],
まぁ、Macなので/var/lib/docker/volumes/submount_node_modules/_data
はMac内の仮想環境(Docker.qcow2)に含まれており、ホスト側からも直接は参照できませんが…
コンテナ間の共有
さて、作ったnode_modules
ボリュームコンテナは他のコンテナとも共有できます。
version: '3.0' services: webpack: build: context: . dockerfile: Dockerfile_webpack restart: always command: 'node node_modules/.bin/webpack --watch' volumes: - .:/app - node_modules:/app/node_modules + work: + image: ubuntu + restart: always + command: 'tail -f /dev/null' + volumes: + - node_modules:/test_node_modules volumes: node_modules: driver: 'local'
新たにwork
というコンテナを追加して、node_modules
を/test_node_modules
にマウントしています。この領域への操作がwebpack
コンテナからもwork
コンテナからも共有できるかを確認します。
-- workコンテナからファイルを作成 denzownoMacBook-Pro:submount denzow$ docker exec submount_work_1 touch /test_node_modules/from_worker -- webpackコンテナからも見えている denzownoMacBook-Pro:submount denzow$ docker exec submount_webpack_1 ls -l /app/node_modules/from_worker -rw-r--r-- 1 root root 0 Mar 18 01:38 /app/node_modules/from_worker
-- webpackコンテナからファイルを作成 denzownoMacBook-Pro:submount denzow$ docker exec submount_webpack_1 touch /app/node_modules/from_webpack -- workコンテナからも見えている denzownoMacBook-Pro:submount denzow$ docker exec submount_work_1 ls -l /test_node_modules/from_webpack -rw-r--r-- 1 root root 0 Mar 18 01:44 /test_node_modules/from_webpack
相互に作製したファイルが見えていることがわかります。
まとめ
dockerのData Volume周りを少し調べました。まだ雰囲気でやっているところが多いですが引き続き使いながら覚えていこうと思います。