❄️

Reactアプリをdocker composeとECS(Fargate)でデプロイする

2022/12/28に公開

はじめに

アプリケーションをコンテナ化するのが主流となっている昨今において、Dockerイメージの管理やDockerコンテナの運用をクラウド上で完結させることが多くなってきています。
AWSではそのためのサービスとして、イメージ管理のためのECR、コンテナ運用のためのECSが提供されています。
また、DockerとAmazon ECSの統合により、開発者はDocker Compose CLIを使用することで、1つのDockerコマンドでAWSコンテキストをセットアップし、ローカルコンテキストからクラウドコンテキストに切り替え、迅速かつ容易にアプリケーションを実行することができます。

今回はReactのDockerアプリケーションを対象として、AWSのECRとECS、Docker Compose CLIを用いてデプロイを行います。
また、こちらで作成したリソースのCI/CD環境の構築をこちらの記事にて公開しているのでよかったら参考にしてください。

業務にて行なった内容のメモとして執筆します。誤りや指摘などありましたらコメントにて教えていただけると嬉しいです。

前提・注意点

・AWS CLIがインストールされていること
・AWS IAMにて適切なユーザーが作成済みであること(AmazonEC2ContainerRegistryPowerUserロールが必須です)
・Docker Desktopがインストールされていること
・Nodeがインストールされていること
・以下に示すコード、コマンド内の< >で囲まれた内容は適宜修正が必要であること

手順

デフォルトレジストリに対して認証する

まずデフォルトレジストリに対してDocker CLIを認証します。これによってdockerコマンドは Amazon ECR を使用してイメージをプッシュおよびプルできます。AWS CLI には、認証プロセスをシンプルにする get-login-password コマンドがあり、ログインして認証を行います。

$ aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com

ここでつまずく場合はconfigの設定がうまくいっていない可能性があります。適切な情報がconfigに登録されているか確認すると良いです。

ECRにリポジトリを作成

Dockerイメージを保存するためのリポジトリを作成します。ここではreact-ecs-sampleという名前で作成します。

$ aws ecr create-repository \
    --repository-name <react-ecs-sample> \
    --image-scanning-configuration scanOnPush=true \
    --region <region>

実際に作成されていることが確認できます。

Reactプロジェクトの作成

create-react-appコマンドで生成されるReactプロジェクトを用います。

$ npx create-react-app <react-ecs-sample> --template typescript
$ cd <react-ecs-sample> 

デプロイファイルの作成

$ touch Dockerfile docker-compose.yaml

デプロイ用のDockerfile, docker-compose.yamlを下記内容にて作成します。

Dockerfile
FROM node:14-alpine as builder

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY ./ ./

EXPOSE 80

RUN npm run build

FROM nginx:1.15-alpine

COPY --from=builder /app/build /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]
docker-compose.yaml
version: "3.8"

services:
  react-ecs-sample:
    container_name: react-ecs-sample
    image: <XXXXXXXXXXXX>.dkr.ecr.<region>.amazonaws.com/<react-ecs-sample>:latest
    ports:
      - 80:80
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 2048M

リソースの細部についてはyamlファイルに追記することで設定が可能です。
(参考:https://docs.docker.com/cloud/ecs-compose-features/

最終的なディレクトリ構成は次のようになります。

$ tree -L 1
.
├── Dockerfile
├── README.md
├── docker-compose.yaml
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
└── tsconfig.json

ECRにDockerイメージをプッシュ

まず、DockerfileからDockerイメージをビルドし、タグをつけます。

$ docker build -t <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<react-ecs-sample> .

ECRにDockerイメージをプッシュします。

$ docker push <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<react-ecs-sample>:latest

実際にイメージが追加されていることを確認できます。

ECS contextの作成

$ docker context create ecs <react-ecs-sample>

コマンドを実行し、react-ecs-sampleという名前のECS Dockerコンテキストを作成します。すでにAWS CLIをインストールして設定しているので、Amazonに接続するための既存のAWSプロファイルを選択します。

作成したコンテキストを使用します。

$ docker context use <react-ecs-sample>

docker composeでECSへデプロイ

$ docker compose up

を実行してしばらく待ちます。すると、

ECSのFARGATEタスクがRunningになっていることが確認できます。
実際にEC2 -> Load balancersからDNSを確認し、リソースにアクセスするといつものマークが確認できました!

参考

使用したコード
https://github.com/maximum-maximum/react-ecs-sample
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/getting-started-cli.html
https://docs.docker.com/cloud/ecs-integration
https://qiita.com/taketakekaho/items/6b3ab23100e2731ce586
https://casualdevelopers.com/tech-tips/how-to-deploy-dockerized-react-application-to-aws-with-ecr-and-ecs-ec2

Discussion