Help us understand the problem. What is going on with this article?

LaravelアプリケーションをAWS上のDockerで動かす

概要

LaravelのアプリケーションをAWS上のDockerで動かすための環境を構築します。
具体的には、以下を行います。

  1. コンテナを構築するためのDockerfileを作成する
  2. ECRリポジトリの作成 → AWS CLIで作成
  3. 1.で作成したDockerイメージをECRにをpushする
  4. ECSの環境構築 → マネジメントコンソールから作成

前提条件

  • AWS CLIがインストールがインストールされていること

コンテナを構築

phpnginxの2つのコンテナを構築します。Dockerfileは、それぞれ下記の通りです。

phpコンテナのDockerfile

必要なソースコードをコンテナ内にコピーし、依存ライブラリのインストールを行なっています。

FROM php:7.2.10-fpm-alpine

COPY . .
WORKDIR /var/www/html

RUN set -x && \
  apk update && \
  apk add --no-cache libxml2 libxml2-dev curl curl-dev autoconf $PHPIZE_DEPS && \
  docker-php-ext-install opcache mysqli pdo pdo_mysql xml mbstring curl session tokenizer json && \
  curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && \
  composer global require hirak/prestissimo && \
  composer install && \
  chmod -R a+w storage/ bootstrap/cache

COPY ./docker/php/config/php.ini /usr/local/etc/php/php.ini
COPY ./docker/php/config/docker-php-ext-opcache.ini /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini

nginxのDockerfile

default.confの設定を行なっています。
publicディレクトリ配下は、nginxコンテナに配置しています。

FROM nginx:1.15.5-alpine

ADD ./docker/nginx/config/default.conf /etc/nginx/conf.d/default.conf

RUN mkdir -p /var/www/html/public
ADD ./public/ /var/www/html/public

.dockerignoreの追加

Dockerのイメージを小さくするために、.dockerignoreを追加します。
node_modulesのような容量が大きいものは追加しておく方がいいと思います。

.dockerignoreについては、下記の記事に詳しく説明されていますので載せておきます。
.dockerignore アンチパターン

ECRにDockerイメージをpushする

ECRとは

ECR(Amazon Elastic Container Registry)は、Dockerのコンテナイメージを保存しておくためのレジストリサービスです。ECRに保存したコンテナイメージは、Amazon ECSへのデプロイが可能であったり、他の AWS サービスと簡単に連携することができます。

Amazon ECR

事前準備

AWS CLIを使用して、ECR用のプロファイルを作成します。

$ aws configure --profile ecr

リポジトリ作成

phpeginxの2つのリポジトリを作成します。

$ aws ecr create-repository --repository-name php --profile ecr
$ aws ecr create-repository --repository-name nginx --profile ecr

マネジメントコンソールで作成する場合は、以下の通りです。

Amazon ECR > Repositoriesを選択し、リポジトリの作成をクリックします。
スクリーンショット 2019-02-26 16.07.08.png

リポジトリ名を入力し、リポジトリの作成をクリックして、リポジトリを作成します。
スクリーンショット 2019-02-26 16.08.30.png

nginx/phpコンテナのビルド

上記で作成したリポジトリ名と同じになるように、dockerイメージ名を指定しビルドします。
タグにはlatestとしていますが、必要に応じて変更してください。

$ docker build -t {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php:latest -f docker/php/Dockerfile .
$ docker build -t {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest -f docker/nginx/Dockerfile .

以下の通りDockerイメージが作成されているはずです。

$ docker image ls
REPOSITORY                                                TAG                 IMAGE ID            CREATED             SIZE
************.dkr.ecr.ap-northeast-1.amazonaws.com/php     latest              e7cc55e81372        23 seconds ago      376MB
************.dkr.ecr.ap-northeast-1.amazonaws.com/nginx   latest              c9bfc2840cbc        3 minutes ago       18.2MB

ECRにログイン

ECRにログインする為のパスワードを取得します。

$ aws ecr get-login --region ap-northeast-1 --no-include-email --profile ecr

以下のコマンドが表示されるので、全てコピペし、docker loginでログインします。

docker login -u AWS -p password https://{AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com

Login Succeededと表示されればログイン成功です。

~/.docker/config.jsonを確認するとauthsに追加されていることが確認できます。

~/.docker/config.json
"auths": {
        "{AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com": {}
    },

ECRへDockerイメージをpush

上記で作成したリポジトリにDockerイメージをpushします。

$ docker push {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php:latest
$ docker push {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest

ECSの環境構築

セキュリティグループの作成

ECSを構築する前に、以下を実現するためのセキュリティグループを2つ作成します。

  • インターネットからALBの 443/tcp に対するアクセス許可
  • ALBからphpコンテナの 80/tcp に対するアクセス許可

ALBのセキュリティグループ

  • 外部から 443/tcp へのアクセス許可

以降の手順で作成するALBを割り当てます。

ECSサービスのセキュリティグループ

  • ALBのセキュリティグループから 80/tcp へのアクセス許可

ECSサービスのセキュリティグループとしてますが、実際にはECSでクラスターを作成する際にEC2インスタンスに割り当てるセキュリティグループです。

ALBを作成する

通常のALB作成手順に従ってください。
セキュリティグループは、上記で作成したALBのセキュリティグループを割り当てます。

ALBを利用せずにECSをPublicサブネットに配置する場合は、作成する必要はありません。

これ以降、ECSの構築を行なっていきます。

タスクを定義する

コンテナの起動方法をタスクの定義として登録します。
phpコンテナとnginxコンテナの組み合わせを定義していきます。

Amazon ECS > タスク定義から、新しいタスク定義の作成を選択します。
起動タイプは、EC2を選択します。

タスクとコンテナの定義の設定

項目
タスク定義名 sample-api
タスクロール なし
ネットワークモード default

補足:
タスクロールは、コンテナ内から他のサービスにアクセスするためのロール設定です。
ネットワークモードについては、下記の記事にわかりやすくまとめられていましたので、掲載します。
ECSでEC2インスタンスを利用する際のネットワークモードについて調べてみた | DevelopersIO

次に、コンテナの定義で、phpコンテナとnginxコンテナを追加します。

phpコンテナを追加

項目
コンテナ名 php
イメージ {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php:latest
作業ディレクトリ /var/www/html
メモリ制限(MB) ハード制限 300(MB)

nginxコンテナを追加

項目
コンテナ名 nginx
イメージ {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
メモリ制限(MB) ハード制限 300(MB)
リンク php
ポートマッピング tcp 80:80

以上で設定は完了です。作成を押下して、タスクの定義を作成します。

ECSクラスタを作成する

Amazon ECS > クラスターから、クラスターの作成を選択します。
クラスターテンプレートの選択は、EC2 Linux + ネットワーキングを使用します。

インスタンスの設定

項目
クラスター名 sample-api-cluster
EC2 インスタンスタイプ t2.micro
プロビジョニングモデル スポット
スポットインスタンスの配分戦略 最低価格
インスタンス数 1
Maximum bid price (per instance/hour) 10($)

補足:

スポットインスタンスは中断される可能性があります。中断できないアプリケーションに対しては、スポットインスタンスを使用しないことをお勧めします。
クラスターの作成 - Amazon Elastic Container Service

sshログインを可能とする場合、キーペアを指定している必要があります。
この場合、セキュリティグループで22番ポートも解放してください。

ネットワーキング
VPCは、ALB作成で指定したVPC指定。
セキュリティグループは、作成済みのECSサービスのセキュリティグループを指定。

コンテナインスタンス IAM ロール
デフォルトで選択されているecsInstanceRoleを指定。

スポット群 IAM ロール
デフォルトで選択されているecsSpotFleetRoleを指定。

以上で設定は完了です。作成を押下して、クラスタを作成します。
クラスタが作成されると、コンテナが起動するEC2インスタンスが作成されます。

サービスを作成する

Amazon ECS > クラスター > サービスタブから、作成を選択します。

項目
起動タイプ EC2
タスク定義 sample-api
クラスタ sample-api-cluster
サービス名 sample-api
サービスタイプ REPLICA
タスクの数 1

Elastic Load Balancing(オプション)

項目
ELB タイプ Application Load Balancer
サービス用の IAM ロールの選択 デフォルトで選択されているecsServiceRoleを選択
ELB 名 作成したALBを選択

負荷分散用のコンテナ

nginx:80:80を指定し、ELBへの追加を選択。
ターゲットグループ名に、作成したALBに紐づくターゲットグループを選択を選択。

以上で、ECSの環境構築は完了です。

動作確認

作成したALBのDNS名にアクセスし、動作確認を行います。

Fargateに移行

この記事で作成した環境をFargateに変更する手順を簡単にまとめました。
ECSのバックエンドをEC2からFargateに変更

参考記事

下記を参考にさせていただきました。
【AWS】初めてのECR
LaravelアプリケーションをローカルでもAWSでもDockerで動かす

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした