Dockerは怖いけどdocker-composeは怖くない

## この記事のターゲット

この記事は筆者の同僚エンジニアに向けて書いています。
まだ`Docker`を触ったことがない人に対し、簡単ではありますが開発環境として`Docker`を利用する魅力を記述していきます。

また当然ですが業務上書けないことは書きませんし、インターネット上に晒しても問題ない程度に無難に仕上げるつもりです。

忙しい人は[最後](https://qiita.com/AJ_Fujijun/items/d851859f87085d3d1296#%E3%81%98%E3%82%83%E3%81%82%E3%81%86%E3%81%A1%E3%81%AE%E4%BC%9A%E7%A4%BE%E3%81%A7%E3%81%AE%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%AEdocker%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95%E3%81%AF)だけ見れば良しということで

## WEBアプリケーションの開発環境

WEBアプリケーションを開発するにあたり、一般的には最低限として以下のような環境の準備が必要です。

* `プログラミング言語の コンパイラ or インタプリタ`
* `WEBサーバ（特に複数のWEBアプリケーションを開発する場合やより本番構成に近くする為）`
* `ミドルウェア類（RDBMSやKVS、Elasticsearchなど）`

環境を準備するにあたり、これらの動作環境は開発マシン上に用意するすることが一般的ですが、さらに分類すると以下の3パターンのいずれかを利用する開発が一般的です。



* `Windows や Mac などに直接環境を構築する`
* `VirtualBoxやHyper-VにVM(Debian系やCentOS系)を用意し、VMマシン上に環境を構築する`
* `Docker環境を構築し、各種環境をDockerコンテナとして構築・動作させる`

これらの3パターンについて個人的な見解として評価をすると以下のようになります。

##### ▼直接環境を構築する場合

これは一番**やってはいけない**パターンです。

ホストマシン上に環境構築する場合は、動作させるソフトウェアのバージョン管理の疲弊します。
疲弊しないために自身のマシン内のソフトウェア類のバージョンに合わせてWEBアプリケーションの開発をすることになり、脆弱性を含んだソフトウェアを量産することになるでしょう。

##### ▼VMマシン上に環境を構築する場合

VM上にWEBアプリケーション毎の環境を構築し、WEBアプリケーションが変わるたびにVMを切り替えます。
ホストマシンとVM間でWEBアプリケーションのソースコードを共有し、`作業はホストマシン` `実行はVM` と役割を分けるのが一般的です。

また、私の過去の経験上、RDBMS内のデータやWEBサーバの設定ファイルなどまでホストマシン側に共有していない人が多く、VM様がご愁傷様した場合にスナップショットがあればそれから復元し、ない場合はゼロから作ることになります。

ただしスナップショットがすでにバグっていることも…（　＾ω＾）

なお、同一VM上に複数のWEBアプリケーションの開発環境を構築する場合は、上記の「▼直接環境を構築する場合」と何も変わりませんので何も意味を成しません。

##### ▼Dockerコンテナとして構築・動作させる

おすすめです。
仕組みは後述します。

## どの開発環境を選べばよいか

正直好きな環境を選べばよいと思います。
当然ですが既存のWEBアプリケーションの開発環境まで`Docker`に移行する必要はないと思います。
(でも移行する場合は割と簡単にできるので、移行しても良いかと…)

さて、ここからが本題ですが、**これからの開発であれば迷わずに`Docker`を利用することをお勧めします**。

## 開発環境でDockerを利用する

##### ▼Dockerって何？

`Docker`ではプログラムの実行環境や`RDBMS`などの各環境を`Dockerイメージ`として作成します。
この`Dockerイメージ`を動作させたものが`Dockerコンテナ`と呼ばれます。
`Dockerコンテナ`は単にホストマシンのchrootさせたプロセスとして動作するイメージに近いです。

また`Docker`では原則的に、WEBアプリケーションのソースコードやミドルウェア類の設定ファイルはホストマシンで用意し、以下のどちらかの方法でDockerコンテナから利用できるようにします。

* 実行時に共有する（変更が多いWEBアプリケーションのソースコード等が該当）
* `Dockerイメージ`に予め入れておく（変更が少ないミドルウェアの設定ファイル等が該当）

なお、RDBMS等の永続化したいデータについてもホストマシン側に置くようにし、RDBMSのDockerコンテナがそこに変更を行うように設計します。

以下の評判の良い記事が参考になります。

* [いまさらだけどDockerに入門したので分かりやすくまとめてみた](https://qiita.com/gold-kou/items/44860fbda1a34a001fc1)(@gold-kou殿の記事)
* [【図解】Dockerの全体像を理解する -前編-](https://qiita.com/kotaro-dr/items/b1024c7d200a75b992fc)(@kotaro-dr殿の記事)

`Docker`は優秀ではありますが、**それ単体で利用する場合は**コマンドライン上で長ったらしいコマンドを実行して動かすことになります。
とてもじゃないけど開発で利用する際には、**運用していくのはしんどいです…**。
Dockerを食わず嫌いする人や触ってみたけど難しいなと感じて挫折した人の大半はここで終わっているように感じてます。

さて、その問題を`docker-compose`を利用して解決します。

## `docker-compose`って何？

WEBアプリケーションの開発において、`Dockerコンテナ`をまとめて動作させることが多いため、`docker-compose`という**オーケストレーションツール** を利用するのが一般的です。

以下の評判の良い記事が参考になります。

* [docker-composeを使うと複数コンテナの管理が便利に](https://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce)(@y_hokkey殿の記事)

`docker-compose`を利用することで、`Dockerコンテナ`の管理が用意となり、**複数のコンテナを協調させて動作させる**ということは、ある意味のVMでやりたいことも可能となります。

VMを利用する場合はVM毎にCPUコアやメモリを割り振る必要がありますが、`Docker`+`docker-compose`を利用することにより「**1台のバーチャルハードウェア上で複数のVMを動作させる**」相当のことが可能になります。

つまり案件（またはWEBアプリケーション）毎に`docker-compose`で構築することでVMをスイッチする手間がなくなり、WEBアプリケーションエンジニアがハッピーになれます。

## じゃあうちの会社でのお勧めのDocker開発方法は？

近年勢いのある`PHP`のWAFである`Laravel`の利用が増えてきました。
Dockerを利用して`Laravel`の開発を行うのであれば、個人的には`Laradock`一択だと思います。

主な理由は…

* ドキュメントがしっかり整備されている（英語だけど）
* 超たくさん色々なミドルウェアが整備されている（Laravelの$\tiny{ほぼ}$すべての機能を利用できる）
* 活発に更新されている
* めちゃめちゃ簡単に動かせる（主に環境変数ファイルとdocker-compose.ymlファイルだけ触ればよい）
* 筆者が慣れているため社内に提供できる情報が多い

[【Laradock公式ページへのリンク】](https://laradock.io/)

Laradockを[Win10 Home ＋ `Docker Toolbox`で動作させる際に少しハマる](https://qiita.com/AJ_Fujijun/items/72a8a2dc585387c9abad)ことがあるのは気になりますけどね…（　＾ω＾）