概要
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で動かす