LaradockをAWS Elastic Beanstalkで使用する

Laravelでは[Laradock](https://github.com/laradock/laradock)を使うことによって簡単にDockerで環境を構築できます。

「Laradockを本番/開発環境でも使いたい」という方のために、今回はLaradockを[AWS Elastic Beanstalk](https://aws.amazon.com/jp/elasticbeanstalk/)で使用する方法をご紹介します。

#概要
- Elastic Beanstalkは複数コンテナ環境（Multi-Container Docker）を使用
- LaradockからはNginxとPHP-FPMを利用

今回はLaradockのv5.85を使用しますが、基本的にどのバージョンでも実現可能です。
最終的な構成は[GitHub (hareku/laradock-aws-elastic-beanstalk)](https://github.com/hareku/laradock-aws-elastic-beanstalk)で公開しています。

#実装方法

##AWS ECR にイメージを保存
まずは使用するイメージをAWS ECRに保存します。

NginxとPFP-FPMをビルドしましょう。

```
docker-compose build nginx php-fpm
```

次にAWS ECSのコンソール画面からそれぞれのリポジトリを作成します。（nginx、php-fpm）
作成後、ビルドしたイメージにタグを付けプッシュします。

```
docker tag nginx:latest 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
```

```
docker push 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
```

（プッシュなどの操作はECSコンソール画面にも説明があるので省略します）

##Dockerrun.aws.jsonの作成

以下のように記述します。

```Dockerrun.aws.json
{
    "AWSEBDockerrunVersion": 2,
    "volumes": [
        {
            "name": "application",
            "host": {
                "sourcePath": "/var/app/current/laravel"
            }
        },
        {
            "name": "php-ini",
            "host": {
                "sourcePath": "/var/app/current/php-fpm/php71.ini"
            }
        },
        {
            "name": "nginx-sites",
            "host": {
                "sourcePath": "/var/app/current/nginx/sites"
            }
        }
    ],
    "containerDefinitions": [
        {
            "name": "php-fpm",
            "image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/php-fpm:latest",
            "essential": true,
            "memory": 128,
            "mountPoints": [
                {
                    "sourceVolume": "application",
                    "containerPath": "/var/www"
                },
                {
                    "sourceVolume": "php-ini",
                    "containerPath": "/usr/local/etc/php/php.ini"
                }
            ]
        },
        {
            "name": "nginx",
            "image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest",
            "essential": true,
            "memory": 128,
            "mountPoints": [
                {
                    "sourceVolume": "application",
                    "containerPath": "/var/www"
                },
                {
                    "sourceVolume": "nginx-sites",
                    "containerPath": "/etc/nginx/sites-available"
                }
            ],
            "links": [
                "php-fpm"
            ],
            "portMappings": [{
                "hostPort": 80,
                "containerPort": 80
            }]
        }
    ]
}
```

##Volumesのファイルを作成

次にDockerrun.aws.jsonのvolumesで指定されているファイル等を作成していきます。

###Laravelフォルダを作成
applicationボリューム（/var/app/current/laravel）を作成します。/var/app/current/というのはDockerrun.aws.jsonがあるディレクトリです。

その階層にlaravelフォルダ（composer.jsonなどがあるアプリ本体）を設置します。
フォルダ名はlaravelとなっていますが、任意なので変更しても構いません。

###php-iniとnginx-sites を作成
Laradockのdocker-compose.ymlには、php-fpmのvolumeに以下が指定されています。
`./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini`

build時に環境変数のPHP_VERSIONが71である場合は、「./php-fpm/php71.ini」が必要です。
そのため「/var/app/current/php-fpm/php71.ini」というファイルを作成します。このファイルはLaradockからそのままコピーします。

nginxも同様で「/var/app/current/nginx/sites」フォルダを作成し、そこにdefault.confを設置します。
設定は以上です。

##Elastic Beanstalkへアップロード

作成したDockerrun.aws.jsonやlaravelフォルダを1つのzipファイルにまとめ、Elastic Beanstalkへアップロードすれば完了です。
ただデプロイ毎に圧縮するのは面倒なので、CircleCIなどを利用して自動デプロイを行うことをおすすめします

##注意点など
###Queueや定期タスクが必要な場合
Elastic Beanstalkではcronをインストールできないため、Laradockのphp-workerなどは利用できません。
Queueや定期タスクが必要な場合は、[laravel-aws-worker](https://github.com/dusterio/laravel-aws-worker)というパッケージを使用します。このパッケージをインストールしてWorker環境を別に作成することで、Queueや定期タスクを処理してくれます。

###php-fpmのmemory_limitを変更する場合
php-fpmの.iniファイル（laravel.iniなど）でmemory_limitを128Mから256Mに変更する際は、Dockerrun.aws.jsonのphp-fpmにある「memory」も256へ変更しておきましょう。

Dockerrun.aws.jsonだけが128のままであると、メモリーエラー時に502エラーとなってしまいます。