概要
LaravelのアプリケーションをAWS上のDockerで動かすための環境を構築します。
具体的には、以下を行います。
- コンテナを構築するためのDockerfileを作成する
- ECRリポジトリの作成 → AWS CLIで作成
- 1.で作成したDockerイメージをECRにをpushする
- ECSの環境構築 → マネジメントコンソールから作成
前提条件
- AWS CLIがインストールがインストールされていること
コンテナを構築
phpとnginxの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 サービスと簡単に連携することができます。
事前準備
AWS CLIを使用して、ECR用のプロファイルを作成します。
$ aws configure --profile ecr
リポジトリ作成
phpとeginxの2つのリポジトリを作成します。
$ aws ecr create-repository --repository-name php --profile ecr
$ aws ecr create-repository --repository-name nginx --profile ecr
マネジメントコンソールで作成する場合は、以下の通りです。
Amazon ECR > Repositoriesを選択し、リポジトリの作成をクリックします。

リポジトリ名を入力し、リポジトリの作成をクリックして、リポジトリを作成します。

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に追加されていることが確認できます。
"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で動かす