Amazon Linux による LAMP 環境を構築し、強制的に静的コード解析をする docker-compose 

## 概要
LFTV のレビューおじさんです。Xin Chao. ホーチミンは雨季です。雷やばい。

さて、PHP の Dirty code を見るのにも疲れてきました。ちょっとでも楽をしたい、その一心で PSR-2 で書いてくれとか if や foreach のネストはほどほどにしてくれとか、レビューする前に最低限これくらいやってくれよというルールを決めて、布教に勤しむわけですが、まぁ守られない。最初の1回だけ。

でも、みんなが守れないルールはルールが悪いんです。

ベトナムに限らず東南アジアではスキルアップ・給与アップのためにジョブホッピングしてくことが労働者の権利として認められており、基本的には教えてもいなくなっちゃうので、新しい人が来たらまた同じことの繰り返し。そんなのやってられないので、システムで守りましょうと、当たり前に考えるわけです。

とりあえず最低限ということで、コードの静的解析を pre-commit に仕込んで、汚いコードは commit できないようにすれば良い。。。んですが、これとこれとこれをインストールして、pre-commit にはこれを書いて、と OS もバラバラ、スキルもバラバラな人たちに確実に伝えるのは、割と大変です。

良いソフトウェアは、マニュアルが必要ない。

という訳で、何も考えず、何も特別なことをしなくてもルールを守らせるような仕組みを作ってみようと。やってることは、正直バカバカしいです。それくらい、ローカルにインストールしろや！と思います。

あと、取り扱う開発環境は猫も杓子も AWS Amazon Linux ですが、ベトナムは南シナ海の情勢次第で、ネットワークが不安定であり、東京リージョンが遠くてやってられないことが多々あるので、できるだけローカルで開発・確認したく、Amazon Linux による一般的な LAMP/LNMP 環境も構築してみました。あ、Docker です。

コードの静的解析は、諸々検討した結果、
### PHP
- Phan
- phpcs (PSR2)
- phpmd
 
### JavaScript
- Eslint

を利用することにしました。

こんなのみんな考えついてやってるでしょ。と思って探し回りましたが、概念はあちこち書かれているものの、ざっと探して回った限り、具体的なアウトプットが公開されていなかったので、作りました。売れるんじゃない？とも思いましたが、せこいので公開しました。


## 出来上がったもの
[Docker for LAMP/LNMP by AmazonLinux](https://github.com/lifulltechvn/dockerLAMP "Docker for LAMP/LNMP by AmazonLinux")

## 利用イメージ
まず、プロジェクトの git リポジトリのルートディレクトリに、上記からダウンロードした

```
LAMP/
hookinstaller/
toolbox/
docker-compose.yml
```

を配置して配布します。開発者は、ローカルに Docker をインストールする必要はありますが、それはやってもらうとして、git からローカルマシンにソースコードを clone して、

```
$ docker-compose build
$ docker-compose up -d
```

とするだけで（本当はもうちょっとあるけど）、ローカルに持ってきたソースコードの動作をブラウザで確認したり、汚いコードをコミットしようとすると怒られたりすることができるようになります。
開発者は、ローカルで自分の好きな開発環境・ツールで開発することができる上、サーバへのソースコードの同期なども必要なく、管理者は、開発者の環境は何も気にせず守らせたいルールを守らせることができます。

守らせたいルールが変更になった場合、管理者は hookinstaller, toolbox などを必要に応じて修正し、上記コマンドを再度実行させることで再配布することも簡単です。

夢のようですね。


では、それぞれが具体的に何をやっているのか見ていきましょう。

### 動作環境
以下のような Docker 環境で確認しています。

```
$ docker version
Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Thu Apr 26 07:13:02 2018
 OS/Arch:      darwin/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Thu Apr 26 07:22:38 2018
  OS/Arch:      linux/amd64
  Experimental: true

$ docker-compose --version
docker-compose version 1.21.1, build 5a3f1a3
```

### LAMP

Amazon Linux の Image は PHP や MySQL の組み合わせを選べるようにしてあるので、

```LAMP/.lamp_env
##This file for setup version of Middleware - please use only the prodived value. 
##Either apache or nginx are installed, the other need to be NULL 
#mysql (value to add: mysql55, mysql56, mysql57) 
mysql=mysql57 
#apache (value to add: httpd24) 
apache=httpd24 
#nginx (value to add: nginx) 
nginx= 
#php (value to add: php56, php70, php71, php72, phpcustom) 
php=php71 
```
を適当にカスタマイズしてください。

php56, php70, php71 は yum でインストールしていますが、php72 は現時点では yum でインストールできないので、７．２．５をソースコードから入れています。
これら以外の特定バージョンの PHP をインストールしたい場合は、phpcustom を選び、`LAMP/php/phpcustom`にインストール手順を書いて実行すれば良いです。サンプルとして、 5.6.35 をインストールするスクリプトが置いてあります。phpcustom を選んだ場合は、xdegug はインストールされないので、必要であれば、それも phpcustom のスクリプト内に書いてください。

MySQL は、AWS で選べる、５．５系、５．６系、５．７系を選べるようにしました。
apache は、流石にもう ２ 系で良いでしょと選べる風で選べないようになっています。apache でなく、nginx を入れたい場合は、

```
...
apache=
nginx=nginx
...
```

と書いてください。その他細かい設定は、プロジェクトの要件に応じてカスタマイズしてください。

### toolbox

コードの静的解析をするためのツール phpcs, phpmd, eslint が入っています。phing で楽しようとも考えましたが、phpcs 3 系に対応する気配がないので、やめました。
phpcs を 3系にしたかったのは、Laravel などを利用するプロジェクトで phpcs ２系を何も考えずに実行すると、PSR−0 の指摘が非常にうるさいからです。
Eslint は、サンプルとして airbnb に必要なものを npm でインストールしています。動かすのに必要なものを入れてください。

このコンテナは、バックグラウンドで起動しておいて、ローカルからコンテナ内のコマンドだけ呼び出すことで、コード解析だけができれば良いので、Alpine Linux に PHP7 を入れました。コマンドライクに使いたいけど、現時点ではデベロッパーにコマンド打たせることは想定していなくて、後述の hookinstaller で配布する pre-commit 用のおまじないみたいな感じになっています。

PHP系は、composer, Eslint は npm でインストールしています。全部で２０行もないので、見ればカスタマイズは容易かと。
Alpine Linux には基本的に何にも入ってないので、必要に応じて、package のインストールが必要です。
パッケージは以下で検索できます。
[Alpine Linux packages](https://pkgs.alpinelinux.org/packages "Alpine Linux packages")

### hookinstaller

pre-commit を各デベロッパーのプロジェクトディレクトリの .git/hooks/pre-commit にコピーしてるだけです。
pre-commit では、

- PHP の syntax
- phpcs による psr２
- phpmd
- JS の eslint

を toolbox コンテナから呼び出して確認しています。eslint の呼び出し方がスマートではありませんが、まぁいったんこれで。後で変えても簡単に再配布できますし。


その他、package.json とか .php_cs とか ruleset.xml とか .eslintｒｃ.js とかそういうものは、普通に git 管理で良いでしょう。

### phan
これは、省略で良いですかね。

```
$ docker-compose run phan
```

で実行できます。.phan ディレクトリにあれこれ置いたりしますが、ここでは省略。


## まとめ

- プロジェクトリポジトリのルートディレクトリに、諸々配置
- 開発者に以下の２つのコマンドを打たせる

```
$ docker-compose build
$ docker-compose up -d
```

- ハッピー 

という訳で、今後、コードレビューでくだらない指摘をする必要がなくなり、もっと本質的なレビューを行うことができるようになりますね。
LIFULL Tech Vietnam ではベトナム品質を世界一にするため、諸々の取り組みを行っています。随時採用は行っておりますので、ちょっと気になった人はお声がけくださーい。

では、また！