開発環境の変遷は「自前サーバー → クラウド仮想サーバー → Vagrant → Docker (Docker Compose)」です。
Docker Composeは最近使い始めたんですがいろいろ最高にラクすぎてもうだめ。
目次
Dokcer単体の使いづらさをカバーするCompose
Dockerは以前にも少し触ったことがありましたが、そのときはまだ使い方を理解していなかったこともあり、正直使いづらいツールだと思ってそのままでした。
オールインワンで作ってきた経験から、小さくサービスごとに切り出して一度実行するだけのコンテナを作るみたいなのがどうにも慣れなかった感じです。設定ファイルなんかも外部に出さずに直しちゃって、またやり直しみたいな。
Composeを導入することで、そういったDockerの特徴が消えるわけでは勿論ありませんが、Dockerをもうひとつグループ化するような設定ができて格段に使いやすくなっています。
開発環境をネットワークごと増やして分けることができる
最高に便利だと思うのがこれ。docker-compose.ymlも含むDocker関連ファイルはすべてGitリポジトリに納まっているので、ちょっと違う開発環境を増やしたいと思ったら別のところにcloneしてきてdocker-compose upするだけで閉じたネットワークにサーバー一式セットアップが完了します。
コレが本当にやばくて。例えばユニットテストしてる待ち時間に別の調査を進めようかとか、検証するために一から環境が欲しい(けど開発用に作った環境はそのままにしたい)とか、兎に角いろいろ使えます。
特に修正中に別の修正や調査、PRレビューなんかが飛んできたときにgit stashで切り替えるまでもなく、別ディレクトリにcloneしてきていくらでも試せる。
それぞれの環境専用のRDBやNoSQLが用意される
環境が別れるとは、文字通り閉じたネットワークの全てが別れておりMySQLやRedisサーバなどもそれぞれの環境用にサービスが起動しています。
なのでデータが混ざることも無く安全に環境を増やすことが出来てしまう。
またコンテナは使い捨てとなっているため、原則として内部のデータは起動ごとに初期化されてしまいます。ここでNoSQLはともかくRDBのデータは保存したいとなったときも、相対パスでコンテナにファイルをマウントできるのでディレクトリごとに保管できて安心です。
このような設定も、docker-comopse.ymlにまとめて書けるためとてもやりやすい。
ディレクトリ単位でコンテナが管理できる
そしてDockerを敬遠していた私が完全に転んだのがここ。
ディレクトリパスとdocker-comoposeに指定されている名前で管理されているので、環境ごとのディレクトリ直下でdocker-composeを操作すると大量のDockerコンテナがあっても混乱せず扱うことができます。
例えばディレクトリAの下で
$ docker-compose up
を実行すると、そのディレクトリに関連したDockerコンテナ群がまとめて起動します。
別のディレクトリBの下で同じようにupするとディレクトリBに関連したDockerコンテナ群が起動し、それらはAと混ざることがありません。
停止するときも同様にディレクトリの下で
$ docker-compose stop
としてやれば纏めて落とせます。
このように一括で関連するコンテナを対象とした操作ができるため、一サービス一コンテナの勢いでコンテナ分割しても管理が負担になりません。
コンテナの操作を名前で扱える
もう一つ、このディレクトリごとの操作ではコンテナ単体も名前で対象にすることができます。
dockerコマンドでは、稼働しているコンテナを何か操作するときはいちいちIDを調べたりしていましたが、docker-composeではymlファイルで設定した名前がそのまま使えます。
つまりnginxのコンテナだけを止めたいときは
$ docker-comopse stop nginx
となります。もうこれだけで使う理由になる。
またymlファイルでは各サービスの関連づけも行うことができ、これによって例えばphp-fpmサービスを起動させたら自動的にnginxも起動する、みたいなこともできます。
ネットワークが競合しない
開発中に複数のWebサイトを立ち上げたいとかなったときに、nginxを一つのマシンで複数立ち上げるのも面倒な話です。それがディレクトリを分けるだけでできてしまう。
docker-compose.ymlのあるところがそれぞれ別のLANみたいになっているため、その中でユニットテストを走らせたり、一時的にポートフォワードしてブラウザで見たりと他の環境を気にせず自由にやれます。
環境を破棄したいときはディレクトリを消す
用が済んだらまとめて削除。他に影響はありません。
環境をリセットしたいだけであれば、コンテナを削除するとかイメージを削除するとかで作り直すことが出来ます。このときは多少待つことになりますが、一からサーバー構築することを思えば全然手間ではありません。
環境をテキストファイルで共有できる
これはDockerの利点でもありComposeの利点でもあります。Dockerfileやdoker-compse.ymlに書かれた設定を元にイメージをビルドしてサービスが起動されるわけなので、例えばバージョン違いのサービスをテスト用に増やしたいとか、nginxの設定を追加したいだとかとなったときは個別の変更とともにこれらのテキストファイルを編集してコミットすれば開発メンバー全員が環境を合わせることが出来ます。
Vagrantのときはこのあたりもうまく共有できなくて、結局ひな形ファイルからそれぞれが改造していくようなことになっていて、ノウハウの共有などはあまりできていませんでした。
もう開発では手放せない
docker for macの動作が割と軽いことも手伝って、もう開発環境として手放せないと感じています。
Vagrantやその前の環境から考えるとだいぶ変わったなと思いますが、使ってみると各サービスの連携具合など、それぞれのサービスを知っていないと上手く繋げられなかったりもするので、単一サーバーの応用だなと感じるところもあったり。逆にこう、一つのマシン環境内でVirtualHostで一生懸命分けたりとか、そういう経験が生きてるところもあったりします。
Dockerイメージをこのまま本番環境や(サーバーチームではないメンバーも使う)各種テスト環境で稼働させることが出来れば一貫性が出てなおのこと良くなるとは思うのですが、残念ながらまだそこまではできていません。次の目標はそのあたりですね。その前にAWS Batchで別の方向からDockerコンテナを上げてくことになるかもしれないけど…
関連サイト:
とりあえず見てみたいのであれば日本語サイトで良いですが、情報が古かったりするので使うときの参考は英語サイトの最新ドキュメントを見ると良いです。