🐱

Next.jsをAWSのECS×Fargateに自動デプロイのメモ

2021/01/11に公開

※現在は自分用のメモとして記載、公開しています。これから追記&他人にも理解できるようにしていきます!!

■ Next.jsのアプリを作る
・Next.js公式のチュートリアルで!

■ GitHubでローカルリポジトリを作成する
参考URL:
https://qiita.com/gakisan8273/items/6ebaf9217d140ff1f031

■ ※不要であればしなくてもよい:Route53で独自ドメインの設定
参考URL:
https://zenn.dev/hibriiiiidge/books/49ee4063b10cec1df1a2/viewer/c7dc11

■ ECRの準備
参考URL:
https://kleinblog.net/ecs-ecr-hello-world.html

・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:
https://dev.classmethod.jp/articles/ecr-immutable-image-tags/

・VPCなどのネットワークの設定
※参考URLにめちゃくちゃ詳しく書かれています。

ここまで出来たら次!
※ECS(Fargate)は、ALBとともに作成するので、ECSは作らなくてOKです

■ ALBとECSの作成
参考URL:
https://zenn.dev/hibriiiiidge/books/49ee4063b10cec1df1a2/viewer/8364d5

・タスクの定義
※わかりやすくするため、タスク定義名に 『プロジェクト名-definition』

・「コンテナの追加」よりコンテナを作成
※わかりやすくするため、コンテナ名を、『プロジェクト名-container』
※「イメージ」はECRのURLのこと。
※ Next.jsなので、ポートマッピングに3000/tcpを設定
※ DB接続などの環境変数をここで追加する

・サービスの作成
※わかりやすくするため、サービス名を、『プロジェクト名-service』

ロードバランサー用のコンテナ
※わかりやすくするため、ターゲットグループ名を『プロジェクト名-service-tg』

■ NextのCode PipelineでECSデプロイ自動化
参考URL:
https://www.ragate.co.jp/blog/articles/2200

・「ソースステージを追加する」のソースプロバイダーは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:
https://qiita.com/NaokiIshimura/items/e73898244d784d7fbce7

・CodeBuildで『docker Hub のアカウントにログイン』する必要があります。
参考URL:
https://hhhhhskw.hatenablog.com/entry/2020/11/25/180920#4buildspecymlの修正

■ ※不要であればしなくてもよい:HTTPSする
参考URL:
https://zenn.dev/hibriiiiidge/books/49ee4063b10cec1df1a2/viewer/1a1805#4.-ssl-設定をしたコードでの-ecs-のデプロイ

◇ 設定ファイルのまとめ

・ 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:
https://norm-nois.com/blog/archives/3017

Discussion