Reactアプリをdocker composeとECS(Fargate)でデプロイする
はじめに
アプリケーションをコンテナ化するのが主流となっている昨今において、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を下記内容にて作成します。
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 /app/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
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を確認し、リソースにアクセスするといつものマークが確認できました!
参考
使用したコード
Discussion