経緯
Docker Compose を使って複数の似たようなユースケースで検証を繰り返している中で、
- この検証では Apache のドキュメントルートと MySQL のデータを永続化して試験したい
- その検証ではどちらも永続化しないで試験したい
- あの検証ではファイル数が膨大な上にオペレーションでその膨大なファイルに変更ををかけるので Apache のファイル永続化をしているとディスクIOがボトルネックになって検証に時間がかかり過ぎる
という具合に、同じ Docker Compose のベースを使いつつもユースケースに応じてボリュームをマウントするかどうかを条件によって切り分けたくなりました。
検証ごとに別リポジトリにフォークなりブランチなり切っていくと数が多くなってしまい管理しきれなくなる恐れがあるので、なるべくベースのコードは共通にしておきたいところです。
そこで、「同じ Docker Compose のコードで、条件に応じて処理を変化させる(今回はマウントするボリュームを切り替える)」ということが必要になりました。
結果
最初に結果を記すと、今回は docker-compose
を up
する際に -f
オプション を付ける、という方法を選択しました。
ボリュームをマウントしない場合
> docker-compose up -d
ボリュームをマウントする場合
> docker-compose -f docker-compose.yml -f docker-compose.volumes.yml up -d
このように使い分けるイメージです。
コード
上述で指定した各 yml
ファイルは次のようになっています。
docker-compose.yml
version: '3.8'
services:
web:
build:
context: ./apache/docker
dockerfile: Dockerfile
args:
WEB_ROOT_DIRECTORY: $WEB_ROOT_DIRECTORY
## 略
volumes:
# workspace
- ./workspace:/workspace
# docker settings template
- ./template:/template
## 略
db:
build:
context: ./mysql/docker
dockerfile: Dockerfile
## 略
volumes:
# workspace
- ./workspace:/workspace
# docker settings template
- ./template:/template
## 略
オプションなしで使用するデフォルトの docker-compose.yml
はエントリポイントのシェルスクリプトや設定、ログの置き場所など最低限のディレクトリをマウントするに留めています。
docker-compose.volumes.yml
version: '3.8'
services:
web:
volumes:
# apache virtual host
- ./apache/www:/var/www/$WEB_ROOT_DIRECTORY/web
db:
volumes:
# mysql data
- ./mysql/data:/var/lib/mysql/data
一方、ボリュームマウント用の yml
ファイルでは冒頭の通り Apache のドキュメントルート想定のディレクトリや MySQL のデータファイルのディレクトリをマウントするようにしています。
これにより、オプション指定のない場合は後者のファイルが読み込まれないことによりドキュメントルートやデータファイルをマウントせず、オプションを付けるとマウントする、というように挙動を切り替えられる、という寸法です。
ただし、このくらいで済むのでまだ良いですがこれが複雑化すると大量の -f
オプション と Composeファイル による長大なコマンドになってしまう恐れがあるのでその点は要改善ですかね。現時点でも readme.md
とかにコマンドを書いておかないと一々打ち込んでいられないレベルですし。
参考
-f オプション
-f オプションの先
- docker-compose.ymlが環境別に複数ある場合はCOMPOSE_FILEを定義しておくと幸せになれる
- docker-compose で複数環境を構築するときの設定をなるべく DRY に書く – ikasama over technology