Aws Code PipelineでReactjs/Nextのデプロイを自動化!ECSへ展開してみました

Aws Code PipelineでReactjs/Nextのデプロイを自動化!ECSへ展開してみました

CIの構築は色々と選択肢があって迷いますよね。

CircleCI、Jenkins、Aws Code製品と・・。私たちはAwsでワンストップでマネージしたいので、Code Pipeline、CodeBuild、CodeDeployをフル活用しています。今や三種の神器ですね。

今回は、「Reactjs/NextのCode PipelineでECSデプロイ自動化」をご紹介します!

Nextjs&ECSのCode Pipeline開発の流れ

ソースリポジトリはCode Commitでも良いですが、ここはわかりやすくGithubにしておきます。(Githubの方がメジャーなので…)

  1. Code Pipelineプロジェクトを作成
  2. ソースフェーズにGithubをConnect
  3. Code Buildの設定
  4. ECSの設定
  5. Dockerfileを作成しNextjsのビルド疎通
  6. buildspec.ymlでCode Buildのビルドを定義
  7. imagedefinitions.jsonでイメージ情報の定義

Code Pipelineプロジェクトを作成

まずはCode Pipelineでプロジェクトを作成します。Awsの管理コンソールへ移動しパイプラインを作成しましょう。

Code Pipeline作成

Code Pipelineのロールを作成もしくは指定します、ここでは、新しいサービスロールを選択し自動的にロール作成をしてもらいます。自分で事前にロールを作成し渡すことも可能ですが、はっきり言って意味ないのでやめましょう。

Pipelineのロール設定

これでCode Pipelineの作成が終わりました。簡単ですね。次はCode Pipelineの各実行工程を設定していきます。

ソースフェーズにGithubをConnect

宣告通りGithubを利用します。ソースプロバイダーからGithubを選択しましょう。

Githubと入力

Githubを選択すると、Githubへ接続するというボタンが表示れるので、指定のリポジトリへアクセス権限のあるアカウントでコネクションしましょう。

Githubへ接続

成功したら、WebHookでソースコードを調達するリポジトリ及びブランチを指定します。ここで指定したリポジトリとブランチへ、プッシュもしくはPRマージなどされた場合に自動的にデプロイを構築することが可能です。

リポジトリ選択

Code Buildの設定

まず環境変数を指定します、これらの値は後ほどCode Build実行時にbuildspec.ymlから読み込みます。(後述)

名前
IMAGE_TAGlatest
AWS_DEFAULT_REGIONap-northeast-1
IMAGE_REPO_NAME{ECRのリポジトリ名を指定}
AWS_ACCOUNT_ID{ECRのリポジトリのURLにて確認可}
NODE_ENVproduction
環境変数一覧
Code Buildへ環境変数を追加

ビルド内容を作成していきます。

Code Buildプロジェクトを作成

プロジェクトは設定は下記にしてください。Dockerをビルドするので、特権付与をお忘れなく。これを忘れるとビルドフェーズで謎エラーでこけます。

  1. OSにUbuntuを指定
  2. ランタイムにStandard (標準)を指定
  3. イメージでにaws/codebuild/standard:2.0を指定
  4. このビルドプロジェクトを使用して Docker イメージをビルドするため特権付与にチェック

ECSの設定

クラスター、サービス名などを指定します。(ECSでの解説は割愛します)これで、ビルドが全て完了しECRへプッシュした後、ECSがlatestタグにてイメージを取得しサービスへアサインしてくれます。

Dockerfileを作成しNextjsのビルド疎通

ではいよいよ、Dockerfile周りの作成を行います。

Dockerfile

イメージにはNodejsの公式イメージを指定しました。タグでバージョン指定が可能なのでオススメですよ。

FROM node:10.20.1-jessie

# 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"]

また、package.jsonはこのようになっていることを想定します。(お好みで調整ください)

{
  "name": "XXXXXX",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "axios": "^0.19.2",
    "classnames": "^2.2.6",
    "dotenv": "^8.2.0",
    "next": "9.3.6",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-gtm-module": "^2.0.8",
    "react-loading": "^2.0.3"
  }
}

buildspec.ymlでCode Buildのビルドを定義

Githubリポジトリのルートディレクトリにbuildspec.ymlを設置します。Code Pipeline実行時に自動的に読み込まれます。

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 10  
      docker: 18
  pre_build:
    commands:
      - yarn
      - echo Logging in to Amazon ECR
      - $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION})
  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
    finally:
      - echo Build completed on `date`

imagedefinitions.jsonでイメージ情報の定義

Githubのルートディレクトリに、imagedefinitions.jsonファイルを設置します。イメージと紐付けるコンテナーを定義しましょう。

[
    {
      "name": "target-container-name",
      "imageUri": "${AWS_ACCOUNT_ID}.dkr.ecr.${DEFAULT_REGION_NAME}.amazonaws.com/${REPOSITORY_NAME}:${IMAGE_TAG}"
    }
]

これで概ね設定は終わりです。あとはmasterブランチへプッシュしてみてください。Aws Code Pipelineの画面を見るとデプロイが実行されていますよ。カスタムのやり方的次第では、デプロイ後にAws SNSを実行しLambdaをキックし、Slackへ通知を飛ばすことも可能です。

まとめ

Reactjs/Nextだけでなく、Vuejs/Nuxtでに応用の効くCode Pipelineの構築方法をご紹介しました。

基本的にデプロイをローカルから実行するとその人のローカルの環境に依存してバグる可能性が高いので、こう言った共通のデプロイ環境を一つ持っておくのは継続的なインテグレーションで有効です。

是非みなさんも有効活用してみてください。