Docker対応のLaravelアプリケーションをCodeBuildを使用してAWS ECSにデプロイする

必要条件

・DockerがインストールされたWindows、Linux、またはMac PC
・AWSアカウント
・Laravel
・Githubアカウント

Composerを入手してLaravelをインストールする

次のコマンドを実行して、composerを使用して新しいLaravelアプリケーションを作成します。

$ composer create-project --prefer-dist laravel/laravel laravel-docker-aws

githubにリポジトリを作ってプッシュしておく

後ほどAWSのCodeBuildeの設定を行う際にgithubリポジトリを利用するので、適宜コミットとプッシュしておくといいと思います。

$ cd laravel laravel-docker-aws
$ echo "# laravel-docker-aws" >> README.md
$ git init
$ git add README.md
$ git commit -m "first commit"
$ git remote add origin git@github.com:planetsman/laravel-docker-aws.git
$ git push -u origin master

Dockerを構成する

Dockerfileを作成する

LaravelアプリケーションのルートにDockerfileを作成します。 Dockerfileは、ユーザーが画像を組み立てるためにコマンドラインで呼び出すことができるすべてのコマンドを含むテキストドキュメントです。

FROM php:7.3.2-apache-stretch

LABEL maintainer="Your Name. <your@neme.ca>" \
     version="1.0"

COPY --chown=www-data:www-data . /srv/app

COPY .docker/vhost.conf /etc/apache2/sites-available/000-default.conf 

WORKDIR /srv/app

RUN docker-php-ext-install mbstring pdo pdo_mysql \ 
   && a2enmod rewrite negotiation \
   && docker-php-ext-install opcache

Dockerフォルダーを作成する

Dockerイメージを構築するために必要なすべての構成ファイルが配置されるフォルダーを作成してみましょう。 Apache構成ファイル(vhost.conf)を格納するLaravelルートフォルダーにフォルダー.dockerを作成します。 ファイルは実行時にコンテナのサイト利用可能フォルダにコピーされます。

<VirtualHost *:80>
   
   DocumentRoot /srv/app/public
   
   <Directory "/srv/app/public">
       AllowOverride all
       Require all granted
   </Directory>

   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

vhost.confファイルは、Apacheのドキュメントルートを/ src / app / publicに設定します。これにより、Laravelアプリが/ srv / appフォルダにコピーされるため、直接アクセスできます。

Laravelアプリケーションimageをローカルでビルドする

.dockerフォルダーにDockerfileとApache構成ファイルを作成したら、 これでアプリケーションを構築する準備ができました。
コマンドラインでLaravelアプリのルートフォルダーに移動して実行します

$ docker build -t laravel-docker-aws .

Dockerマシンがイメージをビルドします。 これには数分かかる場合があります。
laravel-docker-awsイメージがビルドされたので、次のコマンドでイメージを実行します。

$ docker run -it -p 8001:80 laravel-docker-aws

コンテナーは8001ポートでアクセス可能となります。

スクリーンショット 2020-08-02 17.42.09

CodeBuildビルド仕様ファイルのセットアップ

AWS CodeBuildドキュメントによると、ビルド仕様は、ビルドコマンドを実行するためにCodeBuildが使用するYAML形式のビルドコマンドと関連設定のコレクションです。

buildspec.ymlファイルの名前はそのままで、プロジェクトフォルダーのルートに配置する必要があります。
ただし、AWS CLIまたはAWS Cloudformationを使用して、buildspecファイルに別の名前を付けたり、別の場所に保存したりできます。

buildspec.ymlファイルを作成し、以下のコードをそのファイルにコピーします。

version: 0.2

phases:
 install: 
   runtime-versions:
     php: 7.3
 pre_build: # commands to be run before build
   commands:
   - echo Logging in to Amazon ECR....
   - aws --version
   # login to Elastic container registry
   - eval $(aws ecr get-login --region us-east-1 --no-include-email | sed 's|https://||')
   - REPOSITORY_URI=<YOUR ECR REPOSITORY URI HERE>
   - IMAGE_TAG=<YOUR IMAGE TAG HERE>
 build:
   commands:
   - echo Build started on `date`
   - echo installing composer..
   - composer install
   - echo creating .env file..
   - cp .env.example .env
   - echo generating app key
   - php artisan key:generate
   - echo Building the Docker image...
   - docker build -t $REPOSITORY_URI:latest .
   - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
 post_build:
   commands:
     - echo Build completed on `date`
     - echo Pushing the Docker image...
     - docker image ls -a
     - docker push $REPOSITORY_URI:$IMAGE_TAG 

ビルド仕様には、env、バージョン、フェーズ、アーティファクト、キャッシュなどが含まれています。ここでは、バージョンとフェーズのみを使用します。

必要なバージョンは、ビルド仕様のバージョンを表しています。推奨バージョンであるバージョン2.0を使用します。また、必要なフェーズでは、それぞれのビルドフェーズ中に実行されるコマンドについて説明します。

ビルド仕様ファイルの詳細については、こちらをご覧ください。

インストールフェーズでは、php 7.3ランタイムバージョンを指定しました。 Ubuntu標準イメージ2.0を使用するため、runtime-versionパラメータが必要です。

pre_buildフェーズでは、aws cliバージョンを確認し、AWS Elastic Container Registryへのログインも試みます。レジストリリポジトリのURIと画像タグも定義します。

ビルドフェーズでは、composerをインストールし、Laravel環境ファイルを作成して、アプリケーションキーを生成します。最後に、Dockerイメージを作成してタグを割り当てます。

注:AWS ECRにログインするpre_buildフェーズコマンドで、作業中のAWSリージョンを必ず指定してください:

eval $(aws ecr get-login) --region us-east-1 ....

最後に、post_buildフェーズで、DockerイメージをAWS ECRリポジトリにプッシュします。

これでLaravelアプリケーションがデプロイできるようになります。

Elastic Container Registry Repositoryを作成する

Laravel Dockerイメージを格納するイメージレジストリを作成するため、AWSコンソールのECRダッシュボードに移動します。

スクリーンショット 2020-08-02 22.14.22

リポジトリ名を定義

スクリーンショット 2020-08-02 22.15.38

リポジトリの作成

スクリーンショット 2020-08-02 22.16.59

プシュコマンドの表示をクリックし、buildspec.ymlに設定を反映させる。
※buildspec.ymlの設定で誤るとCodeBuildでDockerイメージを作成するときに失敗するので注意

スクリーンショット 2020-08-02 22.20.53

version: 0.2

phases:
 install: 
   runtime-versions:
     php: 7.3
 pre_build: # commands to be run before build
   commands:
   - echo Logging in to Amazon ECR....
   - aws --version
   # login to Elastic container registry
   - eval $(aws ecr get-login --region ap-northeast-1 --no-include-email | sed 's|https://||')
   // リージョンを適宜変更
   - REPOSITORY_URI=xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/laravel-docker-aws
   // リポジトリURIを自分のプッシュコマンドを参照して変更
   - IMAGE_TAG=1.0
   // IMAGE_TAG = 1.0を設定する。
 build:
   commands:
   - echo Build started on `date`
   - echo installing composer..
   - composer install
   - echo creating .env file..
   - cp .env.example .env
   - echo generating app key
   - php artisan key:generate
   - echo Building the Docker image...
   - docker build -t laravel-docker-aws .
   // プッシュコマンドを参照して変更
   - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
   // プッシュコマンドを参照して変更
 post_build:
   commands:
     - echo Build completed on `date`
     - echo Pushing the Docker image...
     - docker image ls -a
     - docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/laravel-docker-aws:latest
     // プッシュコマンドを参照して変更

ECRリポジトリが設定されます。
Laravelアプリケーションのコンテナーイメージを保存できるようになります。

AWS CodeBuildを構成する

AWSコンソールでCodeBuildを設定してみましょう。 AWSコンソールにログインし、CodeBuildダッシュボードに移動します。

スクリーンショット 2020-08-02 22.33.39

※現在のリージョンで初めてCodeBuildを使用する場合は、おそらく[はじめに]画面が表示されます。

CodeBuildプロジェクトを作成する

[プロジェクトの作成]をクリックして、ビルドプロジェクトを作成します。 ビルドプロジェクトの作成ページが表示されます。

スクリーンショット 2020-08-02 22.36.35

プロジェクト名を付けます。
今回は、ビルドプロジェクトをlaravel-docker-awsと名付けました。 オプションとして、説明ボックスをスキップできます。

下の[ソース]セクションまでスクロールします。 ここで、プロジェクトのソースプロバイダーを指定します。

スクリーンショット 2020-08-02 22.39.38

Githubを選択します。 dockerfile、dockerフォルダー、および作成したビルド仕様ファイルを含むLaravelプロジェクトをプッシュしたことを確認してください。

OAuthボタンをクリックします。 GitHubアカウントでAWS CodeBuildを承認するよう求められます。

[プライマリソースウェブフックイベント]セクションまでスクロールします。 再構築オプションを確認してから、PUSHイベントタイプを選択します。 これは、選択されたGitHubリポジトリに対してPUSHが行われるたびにイメージを再構築するようにCodeBuildに指示します。

スクリーンショット 2020-08-02 22.43.29

CodeBuildのECRアクセスIAMポリシーを作成する

ビルド仕様ファイルのビルド後フェーズでは、DockerイメージをAWS ECRにプッシュしようとします。 これを成功させるには、CodeBuildに必要なアクションを承認する必要があります。

これを行うには、先ほど作成したAWS ECRリポジトリへのフルアクセスを許可するIAMポリシーを作成し、作成したコードビルドプロジェクト用に自動的に作成されたサービスロールにアタッチします。

AWSコンソールでIAMに移動し、[ロール]をクリックします。

codebuild-laravel-docker-aws-service-roleロールを検索/検索します。

コードビルドプロジェクトサービスの役割に付けられているデフォルト名は異なる可能性があることに注意してください。 ただし、ビルドプロジェクトにlaravel-docker-awsという名前を付けた場合、サービスロール名は上記と同じになる可能性が高くなります。

codebuild-laravel-docker-aws-service-roleロールをクリックします。

スクリーンショット 2020-08-03 14.45.17

Amazonが管理するAmazonEC2ContainerRegistryPowerUserポリシーをサービスロールにアタッチします。

スクリーンショット 2020-08-03 14.47.42

AmazonEC2ContainerRegistryPowerUserポリシーを検索して選択し、[ポリシーのアタッチ]をクリックします。

これでポリシーがアタッチされ、CodeBuildパワーユーザーにリポジトリへのアクセスが許可されます。

Laravel Dockerイメージをビルドする

ECRへのCodeBuildアクセスを許可し、CodeBuildプロジェクトを構成したので、Laravel Dockerイメージのビルドプロセスを開始します。

AWSコンソールのCodeBuildダッシュボードに移動します。 laravel-docker-aws CodeBuildプロジェクトをクリックし、[ビルドの開始]ボタンをクリックしてビルドプロセスを開始します。

ビルドプロジェクトをクリックして、起こっていることに関する詳細情報を表示します。

スクリーンショット 2020-08-03 14.50.32

下にスクロールしてテールログをクリックし、ビルドログを表示します。

スクリーンショット 2020-08-03 14.52.04

ビルドプロセスが完了するまで待ちます。 数分かかります。

スクリーンショット 2020-08-03 15.01.44

CodeBuildが正常にビルドされ、DockerイメージがECRリポジトリにプッシュされました。

ECRダッシュボードに移動して、laravel-docker-awsリポジトリ内のイメージのリストを表示します。

スクリーンショット 2020-08-03 15.03.18

ECSをセットアップするために必要になるので、イメージURIをコピーします。

AWS Elastic Container Service(ECS)をセットアップする

Dockerイメージを作成してAWS ECRにプッシュしたので、AWS ECSを使用して実行します。

AWSコンソールのECSダッシュボードに移動します。

スクリーンショット 2020-08-23 16.00.15

Amazon ECSクラスターを作成する

サイドメニューの[クラスター]をクリックします。

スクリーンショット 2020-08-23 16.06.29

[クラスターを作成]ボタンをクリックします。

スクリーンショット 2020-08-23 16.07.04

EC2 Linux + Networkingを選択し、次のステップに進みます。

スクリーンショット 2020-08-23 16.08.54

クラスターに名前を付けます。 この例では、laravel-docker-aws-clusterという名前を付けて、t2.micro EC2インスタンスタイプを選択しています。

他のすべてのパラメーターは、インスタンス構成セクションとネットワークセクションにそのまま残します。

ecsInstanceRoleroleをまだ作成していない場合は、コンテナインスタンスのIAM役割セクションで新しい役割が作成されることを確認してください。

下部の[作成]ボタンをクリックして、ECSクラスターの作成プロセスを開始します。

スクリーンショット 2020-08-23 16.11.50

クラスターが正常に作成されたら、上部にある[クラスターの表示]ボタンをクリックして、作成したクラスターを表示します。

スクリーンショット 2020-08-23 16.13.28

[ECSインスタンス]タブをクリックすると、クラスターにプロビジョニングされたt2.microインスタンスが表示されます。

スクリーンショット 2020-08-23 16.15.05

AWS ECSタスク定義を作成する

タスク定義は、タスクの一部であるコンテナーの数、それらが使用するリソース、それらがどのようにリンクされるか、およびそれらが使用するホストポートなど、アプリケーションのコンテナー情報を指定します。

サイドメニューの[タスクの定義]をクリックし、[新しいタスクの定義を作成]ボタンをクリックします。

スクリーンショット 2020-08-23 16.17.44

EC2を選択し、次のステップに進みます。

スクリーンショット 2020-08-23 16.20.34

タスク定義に名前を付けます。 タスクの役割とネットワークモードのパラメーターはそのままにします。

[コンテナー定義]までスクロールして、[コンテナーの追加]をクリックします。

スクリーンショット 2020-08-23 16.26.24

コンテナー名としてlaravel-docker-aws-containerを指定します。 画像リポジトリのURIも指定します。

画像タグ(1.0または別のタグを使用することを選択した場合は新しいタグ)を必ず指定してください。

128MiBのメモリ制限を指定する


[ポートマッピング]までスクロールして、ホストポートを80に、コンテナーポートを80に指定します。これは、EC2インスタンスのポート80がLaravel Dockerコンテナーのポート80にマッピングされることを意味します。

他はすべてそのままにして、下にスクロールして「追加」をクリックします。

コンテナを追加したら、下にスクロールして[作成]をクリックし、タスク定義を作成します。

スクリーンショット 2020-08-23 16.31.00

タスク定義が作成されたので、タスクを実行する必要があります。

「アクション」をクリックして、「タスクの実行」を選択します。

スクリーンショット 2020-08-23 16.31.56

EC2を選択し、他のパラメーターはそのままにして、タスクの実行をクリックします。

スクリーンショット 2020-08-23 16.35.39

タスクは現在、t2.microインスタンスを含むlaravel-docker-aws-clusterで実行されています。

AWSコンソールのEC2ダッシュボードに移動します。

スクリーンショット 2020-08-23 16.37.36

EC2インスタンスのIPをコピーして、ブラウザーに貼り付けます。

Laravel Dockerコンテナーが実行されています。

これで完了です。
AWS ECSを使用してEC2にdockerイメージを正常にデプロイして実行しました。

最後に

この記事では、Laravelアプリケーション用のDockerをセットアップしました。
 CodeBuildを実装して、Dockerイメージをビルドし、Elastic Container Registryにプッシュしました。
最後に、Amazon EC2でイメージを実行するようにElastic Container Serviceをセットアップしました。

出典

Gbenga Oni(@gbxnga)

Deploy a Docker-ized Laravel Application to AWS ECS with CodeBuild

この記事が気に入ったらサポートをしてみませんか?