Next.jsをECS/Fargateにデプロイする（Docker環境構築編）

## Next.jsをECS/Fargateにデプロイする

### 背景
以下の参考記事を読んでいて、フロントエンドもコンテナ化することで、得られるメリットはそこそこあるのでは？と感じた。とりあえず「Next.jsをECS/Fargateにデプロイする」ことにした。

- 参考記事  
  - [AWS LambdaからECS Fargateへの移行](https://tech.macloud.jp/entry/2021/06/10/104133)
  - [ECS EC2からFargateへ移行した理由とメリット(tapple)](https://pages.awscloud.com/rs/112-TZM-766/images/01_%E3%82%BF%E3%83%83%E3%83%95%E3%82%9A%E3%83%AB%E6%A7%98_%E8%B3%87%E6%96%99.pdf)



### 概要

以下の３記事のステップで、Next.jsをECS/Fargateにデプロイする

- [Next.jsをECS/Fargateにデプロイする（Docker環境構築編）](https://qiita.com/kenji7157/items/79998e3b458f3d28ac58):point_left_tone2: 本記事はこれ
- Next.jsをECS/Fargateにデプロイする（ECR編）
  - 準備中
- Next.jsをECS/Fargateにデプロイする（ECS/Fargateデプロイ編）
  - 準備中

実際に本記事

## Next.jsアプリの構築

- `next-sample-app`というディレクトリ名でNextアプリを構築する

```
$ yarn create next-app --typescript next-sample-app
```

- ローカルサーバーを起動する

```
$ cd next-sample-app
$ yarn dev
```

- http://localhost:3000 にアクセスして、以下の画面が表示されること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397734/515a7894-2004-4758-2438-987cf5477673.png)


## Dockerfileの作成

> Dockerfileとは、新規にDockerイメージを作成するための手順を記したテキストファイル。Dockerイメージの設計図。https://qiita.com/zembutsu/items/24558f9d0d254e33088f

- `/next-sample-app`ディレクトリ配下にDockerfileを作成する

```
$ touch Dockerfile
```

- Dockerfileに以下を記載する

```Dockerfile
# ベースとするDockerイメージを指定
FROM node:14.17.4-alpine

# 以降に続く命令の処理時に使う作業ディレクトリを指定
WORKDIR /usr/src/app/next

# /src/package*.json を ./(WORKDIR)にコピー
COPY /package.json ./
COPY /yarn.lock ./

# Dockerイメージ作成時に実行される
RUN rm -rf node_modules && yarn install --frozen-lockfile
```

## docker-compose.ymlの作成

> docker-compose.ymlとは、複数のコンテナの定義が記載されており、本ファイルを利用してDockerビルドやコンテナ起動をすることができる

- `/next-sample-app`ディレクトリ配下にdocker-compose.ymlを作成する

```
$ touch docker-compose.yml
```

- docker-compose.ymlに以下を記載する

```yml
version: "3"

services:
  nextjs:
    build: .
    ports:
      - "3000:3000"
    container_name: next-sample-container
    volumes:
      - ./:/usr/src/app/next
      # ホストのnode_modulesをバインドしない
      - /usr/src/app/next/node_modules
    command: yarn dev
```

- ymlファイルの各要素の整理
  - version
    - docker-composeで使用するバージョンを定義
    - バージョンによって、docker-compose.ymlの書き方が異なる
  - services
    - アプリケーションを動かすための各要素
    - サービス名は任意で指定可能
    - 定義される各サービスは、imageかbuildのどちらかを指定する必要がある
  - servicesの設定項目
    - build
      - Dockerfileを含むディレクトリのパスか、GitレポジトリのURLを指定
    - ports
      - ホスト側とコンテナ側の両方のポートを指定（ホスト側:コンテナ側）できる
    - container_name
      - デフォルトで生成される名前ではなく、カスタム・コンテナ名を指定
    - volumes
      - ボリュームとしてマウントするパス（場所）を指定
    - command
      - docker-compose up を実行したときに、その内容が実行される


## Dockerイメージの作成

- nextjsサービスのビルドを実行
  - コンテナのDockerイメージが作成される 

```
$ docker-compose build
```

- ビルド完了後にイメージが作成されていることを確認する

```
$ docker image ls
REPOSITORY               TAG           IMAGE ID       CREATED         SIZE
next-sample-app_nextjs   latest        a22749b00ddc   2 minutes ago   1.3GB
```

## コンテナの作成・起動

- イメージファイルからコンテナを作成・起動（バックグラウンド）する
  - 以下実行時にイメージが存在しなければイメージの作成から行ってくれる
```
$ docker-compose up -d
Creating network "next-sample-app_default" with the default driver
Creating next-sample-container ... done
```

- コンテナが作成・起動されていることを確認
  - STATUSが`UP`になっていれば起動している 

```
$ docker ps -a        
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS                    PORTS                                            NAMES
410825ed345e   next-sample-app_nextjs   "docker-entrypoint.s…"   6 minutes ago   Up 5 minutes              0.0.0.0:3000->3000/tcp                           next-sample-container
```

- http://localhost:3000 にアクセスして、以下の画面が表示されること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397734/515a7894-2004-4758-2438-987cf5477673.png)

Next.jsをECS/Fargateにデプロイする（ECR編） に進む