ElasticBeanstalk + Laravel + Dockerを使って15分でオートスケールする環境を構築してアプリケーションをデプロイする


AsiaQuest Advent Calendar 2018の12日目を担当します。

サーバーサイドエンジニアの@makopiです。

今回はElasticBeanstalk+Laravel+Dockerを使用したWebアプリケーションを作成します。

今更ながらElasticBeanstalkを使ってみたら便利だったので記事にしました。

サクッとできるのでおすすめです。

ElasticBeanstalkとは

AWSのリソースを色々組み合わせてアプリケーション用をデプロイできる環境を簡単に構築出来るサービスです。

ElasticBeanstalk専用の管理画面上から関連するリソースの設定を変更することも出来ます。

ElasticBeanstalkの料金自体は無料で、使用したリソースに対しての課金になります。

「サーバーサイドエンジニアが短時間で環境構築したい」みたいなケースにバッチリはまると思います。

メリット

  • AWSやインフラに詳しくなくてもスケールアウトする環境が簡単に作成できる。
  • 環境のコピーがボタン一つで簡単にできるのでdevを複製してstgやprodを簡単に作成できる。
  • Dockerにも対応していてlocal環境とdev/stg/prod等の環境を簡単に揃えられる。
  • とにかく作成が簡単

今回やりたい感じの図

作業の流れです。

  1. Local環境のDocker上でLaravelが動くようにする
  2. 作成したDockerイメージをECRにPushする
  3. ElasticBeanstalkのアプリケーションを作成する
  4. ElasticBeanstalkのdev環境を作成する(DockerイメージとLaravelのソースをデプロイする)

それでは作業して行きます。

LaravelプロジェクトをDockerで立ち上げる

laravelプロジェクトを作成

$ composer create-project laravel/laravel ebsample

Dockerfileとdocker-compose.ymlの作成

Docker上でlaravelを立ち上げるためにDockerfileを記述します。

まずはlaravelをインストールしたディレクトリで新しいフォルダの作成をします。

$ mkdir stacks
$ mkdir stacks/php
$ mkdir stacks/php/conf

作成したディレクトリに以下のファイルを作成します。

stacks/php/Dockerfile
FROM php:7.2-apache

ADD ./conf/000-default.conf /etc/apache2/sites-available/000-default.conf
stacks/php/conf/000-default.conf
<VirtualHost *:80>
    DocumentRoot /var/www/html/public
</VirtualHost>

docker-compose.ymlに関してはlaravelプロジェクトの直下に作成します。

docker-compose.yml
version: "3"
services:
    web:
        build: ./stacks/php
        ports:
            - "8080:80"
        volumes:
            - ./:/var/www/html

dockerでlaravelを動かす

$ docker-compose up -d

localhost:8080で作成したlaravelアプリケーションにアクセスできるようになりました。

ECRにイメージをPushする

ECRの作成

DockerのイメージをPushするためにAWSのコンソールからリポジトリを作成します。

今回はebsampleというリポジトリを作成しました。

ECRにログイン

awscliを入れます。

$ pip3 install awscli --upgrade --user

パスも通しておきます。

$ export PATH=~/Library/Python/3.7/bin:$PATH

以下のコマンドでアクセスキーとシークレットキーを設定します。

$ aws configure

ecrにログインします。
以下のコマンドを実行すると、ログイン用のコマンドが出力されるので実行します。

aws ecr get-login --region ap-northeast-1

以上でecrへのログインが完了です。

ECRに作成したDockerイメージをPush

イメージをbuildします。

$ docker build -t イメージID ./stacks/php/

pushするtagを作成します。

$ docker tag イメージID アカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ebsample

ECRにPushします。

$ docker push アカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ebsample

ElasticBeanstalkアプリケーションを作成

ebコマンドのインストール

まずはコマンドライン上からアプリケーションを作成できるようにebコマンドをインストールします。

$ pip3 install awsebcli --upgrade --user

これでコマンドライン上からElasticBeanstalkが叩けるようになります。

Dockerrun.aws.jsonの作成

Dockerrun.aws.jsonはebにデプロイするために必要な設定ファイルです。
コンテナに使用するイメージやマウントするディレクトリ等を指定します。

Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": 2,
  "volumes": [
    {
      "name": "laravel-app",
      "host": {
        "sourcePath": "/var/app/current/"
      }
    },
    {
      "name": "laravel-storage",
      "host": {
        "sourcePath": "/var/app/current/storage/"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "laravel-app",
      "image": "アカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ebsample:latest",
      "environment": [
        {
          "name": "Container",
          "value": "PHP"
        }
      ],
      "essential": true,
      "memory": 128,
      "mountPoints": [
        {
          "sourceVolume": "laravel-app",
          "containerPath": "/var/www/html/",
          "readOnly":"true"
        },
        {
          "sourceVolume": "laravel-storage",
          "containerPath": "/var/www/html/storage"
        }
      ],
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ]
    }
  ]
}

.ebextensionsの作成

.ebextensionsにはコマンド等を記載したconfigファイルを置いておくとデプロイ中に実行してくれます。
今回はstorageのパーミッションを変更するconfigファイルを作成します。

ディレクトリの作成

$ mkdir .ebextensions

00permission.configの作成

00permission.config
container_commands:
  01chmod_storage:
    command: "chmod -R 777 ./storage"

アプリケーションの作成

eb initでアプリケーションを作成します。
アクセスキーとシークレットアクセスキーを設定していない場合は聞かれるので事前に作成する必要があります。
環境はMulti-container Dockerを使用します。

$ eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
(default is 3): 9

Enter Application Name
(default is "ebsample"): ebsample
Application eb-site has been created.

It appears you are using PHP. Is this correct?
(Y/n): n

Select a platform.
1) Node.js
2) PHP
3) Python
4) Ruby
5) Tomcat
6) IIS
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
11) Java
12) Packer
(default is 1): 8

Select a platform version.
1) Multi-container Docker 18.06.1-ce (Generic)
2) Multi-container Docker 1.6.2 (Generic)
(default is 1): 1
Do you want to set up SSH for your instances?
(Y/n): n

dev環境の作成

$ eb create develop

dev環境を作成します。

これでソースコードがデプロイされます。

作成完了までは数分かかリます。

URLはElasticBeanstalkの管理画面に表示されています。

アクセスすると無事ページが表示されました。

eb createが失敗したら

WARNING: The Multi-container Docker platform requires additional ECS permissions. Add the permissions to the aws-elasticbeanstalk-ec2-role or use your own instance profile by typing "-ip {profile-name}".

上記のエラーでeb deployに失敗した場合はロールに権限が足りていません。

IAMの管理画面からaws-elasticbeanstalk-ec2-roleというロールに
AmazonEC2ContainerServiceforEC2Roleをアタッチします。

$ eb deploy

デプロイし直すとページが表示されると思います。

まとめ

このようにわずかな時間で環境を構築出来ます。

作成したばかりの状態でも、負荷に応じて最大4台までスケールアウトしてくれます。

結構便利なので積極的に使って行きたいと思います。