Next.jsをAWSのECS×Fargateに自動デプロイのメモ
※現在は自分用のメモとして記載、公開しています。これから追記&他人にも理解できるようにしていきます!!
■ Next.jsのアプリを作る
・Next.js公式のチュートリアルで!
■ GitHubでローカルリポジトリを作成する
参考URL:
■ ※不要であればしなくてもよい:Route53で独自ドメインの設定
参考URL:
■ ECRの準備
参考URL:
・Next.jsを、npm run build と npm start して動くことを確認
・Next.js用のDockerfileを作成
FROM node:12
# and mount application
RUN mkdir -p /var/www/ragate.co.jp
WORKDIR /var/www/ragate.co.jp
COPY ./ /var/www/ragate.co.jp
RUN npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "run", "start"]
・念のためローカルでdockerの動作を確認する
$ docker build . -t ecs-test
$ docker images
※docker run のコマンドを知らないので、
Docker Desktopのダッシュボードから、port80番でスタートしています。
・ECRのリポジトリを作成
※イメージのアップはしなくてもOKです、リポジトリを作成するだけ。
後ほどCodePipeline経由でGithubと連携して勝手にアップされるようになるため。
※項目に、『タグのイミュータビリティ』というものがありますが、これは「無効」にしてください。
(コンテナでlatestタグを使えるようにするためのようです)
参考URL:
・VPCなどのネットワークの設定
※参考URLにめちゃくちゃ詳しく書かれています。
ここまで出来たら次!
※ECS(Fargate)は、ALBとともに作成するので、ECSは作らなくてOKです
■ ALBとECSの作成
参考URL:
・タスクの定義
※わかりやすくするため、タスク定義名に 『プロジェクト名-definition』
・「コンテナの追加」よりコンテナを作成
※わかりやすくするため、コンテナ名を、『プロジェクト名-container』
※「イメージ」はECRのURLのこと。
※ Next.jsなので、ポートマッピングに3000/tcpを設定
※ DB接続などの環境変数をここで追加する
・サービスの作成
※わかりやすくするため、サービス名を、『プロジェクト名-service』
ロードバランサー用のコンテナ
※わかりやすくするため、ターゲットグループ名を『プロジェクト名-service-tg』
■ NextのCode PipelineでECSデプロイ自動化
参考URL:
・「ソースステージを追加する」のソースプロバイダーはGitHub(バージョン2)でOK
※もし設定項目が異なっていたら、AWSの詳細などから公式ドキュメントを確認してみる
・「ビルドステージを追加する」において、環境変数について
※AWS_ACCOUNT_ID {ECRのリポジトリのURLにて確認可} は、URL「.dkr」の前の数字のこと。
よくわからなかったらbuildspec.ymlを見よう。
・CodeBuildで『aws ecr get-login-password』あたりで、
『An error occurred (AccessDeniedException) when calling the GetAuthorizationToken …』の認証エラーに毎回引っかかる。
CodeBuildのプロジェクトのロールに、ECRの操作を許可するポリシーをアタッチする。これ絶対忘れるのでメモ。(AmazonEC2ContainerRegistryPowerUserというポリシー)
参考URL:
・CodeBuildで『docker Hub のアカウントにログイン』する必要があります。
参考URL:
■ ※不要であればしなくてもよい:HTTPSする
参考URL:
◇ 設定ファイルのまとめ
・ Dockerfile
FROM node:12
# and mount application
RUN mkdir -p /var/www/ragate.co.jp
WORKDIR /var/www/ragate.co.jp
COPY ./ /var/www/ragate.co.jp
RUN npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "run", "start"]
・ buildspec.yml
printfの 『コンテナの名前』は、『プロジェクト名-container』としたものを入れてください。
(ECS→タスク定義→該当するプロジェクトを選択→コンテナの定義→コンテナ名から確認できます。)
環境変数で取り込めるようにしたかったんだけど、yamlの変数の書き方がよくわからなくて挫折\(^o^)/
version: 0.2
phases:
install:
runtime-versions:
nodejs: 12
pre_build:
commands:
- yarn
- echo Logging in to Amazon ECR
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- echo Logging in to Docker Hub...
- echo $DOCKERHUB_PASS | docker login -u $DOCKERHUB_USER --password-stdin
build:
commands:
- yarn build
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"コンテナの名前","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
finally:
- echo Build completed on `date`
artifacts:
files: imagedefinitions.json
◇ めちゃくちゃ詰まったところ
■ECSのIPアドレスからは見られるのに、ALBから見ると503とか502エラーになる
→VPCとかセキュリティグループとかの問題。まずはデフォルトの環境でやってみよう!!
■起動して一瞬、ALBから見られるけど、すぐに『unhealthy』になってECSのタスクが落ち、これの繰り返しになっている
→Basic認証の問題。Next.jsで、独自の 【Basic認証もどき】をつけていたのですが、
これがALBヘルスチェックで401を返してしまったため、unhealthyに……。
これの原因がほんとうにわからんくて、2週間くらい格闘することに……orz
参考URL:
Discussion