概要
dockerを扱う上で、dev, stg, prdの環境で動かす際の分け方について考えてみました。
環境
- docker 1.13.1
- docker-compose 1.11.1
主な分け方
思いつくのは以下の5つです。
- imageを分ける
- 全環境のconfigファイルをimageに保持させ、RUN時に指定
- templateを埋め込んでおいて、envsubstで環境変数使って書き換える
- data volumeでconfigをマウントして使用する
- 環境変数で設定できるように実装し、envを指定する
a. imageを分ける
まず思いつくのはimageを分ける方法です。
ベースとなるdockerfileをそれぞれ用意してFROMでimageの基礎にし、環境分けのためのconfigの部分を各dockerfileに書く感じです。
メリット
- 分かりやすい
デメリット
- Dockerの同一性・携帯性が崩れる。Dockerfile確認しないと保証できない
- 修正があると全image更新する必要がある
b. 全環境のconfigファイルをimageに保持させ、RUN時に指定
Nodeなどはpm2というプロセスマネージャーがあり、それはconfigファイルを分けて実行時に指定します。
このやり方をdockerでも採用する形です。
メリット
- 既存のプロジェクトをそのままdocker image化できそう
デメリット
- config内容によっては携帯性が崩れる
- config変更でimage作り直しが必要
c. template configを埋め込んでおいて、envsubstで環境変数使って書き換える
あらかじめTemplateとなるconfigと、その中に環境変数で指定できるように設定しておいてenvsubstを使って実行時に書き換える方法です。
メリット
- configは1つなので同一性を保証できる
デメリット
- envsubstの書き方が汚い
d. data volumeでconfigをマウントして使用する
Nginx, Fluentd, Elasticsearchなど最近多くのDockerfileではこのやり方を採用しているように思います。
configを自分で用意して、docker run時にマウントして実行する方法です。
メリット
- 同一性を保証できる
- 他のやり方であるようなimageの作り直し不要
デメリット
- configファイルを自分で用意する必要がある
e. 環境変数で設定できるように実装し、envを指定する
Elasticsearchなど、一部の実行プログラムは環境変数を使って設定することができます。
golangなどもその単一バイナリの携帯性から、環境変数で設定できることが推奨されています。
メリット
- 同一性を保証できる
デメリット
- 対応しているかは中に入っているアプリに依る
まとめ
それぞれ良し悪しがありますが、個人的にはd
のconfigをマウントするやり方が主流になってきそうに感じました。
golangなど、configファイルを別で用意しない場合はe
の環境変数で設定できるやり方が良いと思います。