DockerでNext.js環境構築・デプロイ

## はじめに
:::note info
こちらは、ローカル環境側にNext.jsアプリケーションのソースコードを置いて、Dockerコンテナからローカル環境のコードを参照する方法ではなく(ボリュームマウントやバインドマウント)、直接Dockerコンテナ内でNext.jsアプリケーションを構築する記事になります。
:::


## ホスト環境
* Windows11
* WSL2
* Ubuntu20.04
* Docker Desktop

では、実際にコンテナ作成からデプロイまで確認していきたいと思います。

## 1. ローカル環境の詳細
### ローカル環境のディレクトリ構成

![スクリーンショット (254).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/55074f2c-eba6-cc9a-5560-50f33b201c03.png)

### Dockerfile
`npx darete-next-app`コマンドを直接Dockerfileに記述しています。オプションもすべて公式ドキュメントを参考に書いてます。`

https://nextjs.org/docs/pages/api-reference/create-next-app

```Dockerfile: Dockerfile
FROM node:lts-alpine3.18

RUN apk update && apk add git vim curl

WORKDIR /app

RUN npx create-next-app@latest . \
      --typescript --tailwind --eslint --app --src-dir \
      --import-alias --use-npm

RUN git init

COPY .env /app/ 

COPY ./.vscode/launch.json /app/.vscode/

WORKDIR /
```

### docker-compose.yml
今回はDBを使ってないので`docker-compose.yml`を作成しなくても良いと思うのですが、今後DBコンテナとNext.jsコンテナを接続したアプリケーションを開発することを考慮して作りました。

```yml: docker-compose.yml
version: "3"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    restart: always
    tty: true
```

## 2. docker-composeコマンドでコンテナ起動

### イメージのビルドとコンテナ起動
先述のDockerfileとdocker-compose.ymlファイルを使用してイメージのビルドとコンテナ作成、起動までを行います。
```terminal: terminal
$ docker-compose up -d --build
```

### コンテナ接続
dockerコンテナ内に入り、`.env`ファイルがコピーされているか、実際に`npm run dev`でNext.jsアプリケーションが立ち上がるか確認を行います。コンテナ名は`docker ps`コマンドで確認できます。

```terminal: terminal
$ docker exec -it <コンテナ名> sh

/app # ls -a
.                   .git                next.config.js      postcss.config.js   tsconfig.json
..                  .gitignore          node_modules        public
.env                README.md           package-lock.json   src
.eslintrc.json      next-env.d.ts       package.json        tailwind.config.js

/app # npm run dev
```


## 3. Dev ContainersからDockerコンテナに接続
VScodeの`Dev Containers`を使用して、Dockerコンテナに対して接続を行います。
`Remote Development`拡張機能をインストールすれば`Dev Containers`も合わせてインストールされます。

![スクリーンショット (255).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/49406435-3f34-63f3-6371-ac8d09c785fe.png)
![スクリーンショット (256).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/8292d570-9c32-cfb4-8aea-244aeafd6d11.png)

次にVScode左下の`><`アイコンをクリックして、`実行中にコンテナーにアタッチ`をクリックし、先程作成したDockerコンテナと接続して、Next.jsアプリケーションのコードを開きます。
![スクリーンショット (257).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/f195521f-0bc5-dc65-4069-271f6222ed40.png)
![スクリーンショット (258).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/9a270fbc-6e4a-51bf-8fa7-ed704465fd90.png)
![スクリーンショット (260).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/1789b672-997f-777a-dde5-42567f3e9801.png)

## 4. Vercelにデプロイ
Vercelにデプロイするためのリポジトリを作成し、`git remote add origin <リポジトリURL>`でリポジトリを登録して、コンテナ内のNext.jsアプリケーションコードをGithubにpushします。

Vercelにデプロイする手順については、サバイバルTypeScriptさんの記事をご確認ください。

https://typescriptbook.jp/tutorials/vercel-deploy

最後にちゃんとVercelにデプロイされているか確認します。

![スクリーンショット (261).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/044e8e3e-d3f6-86d2-452f-34e37af7df44.png)

## 番外編: デバッグが出来るか

https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/debugging

上記ののNext.jsのドキュメントを参考に`launch.json`の設定ファイルをそのままコピーし、ブレークポイントを設定してF5キーでサーバーを立ち上げてから `http://localhost:3000`にアクセスしたところ、ブレークポイントで停止していることが確認できました。

![スクリーンショット (262).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/03491997-7318-27b3-839f-3165157915cf.png)

## 終わりに
最後まで記事をご覧いただきありがとうございました。

間違い等ありましたらご指摘いただけると幸いです:bow:

## 参考

https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/debugging

https://typescriptbook.jp/tutorials/vercel-deploy

https://keikenchi.com/build-nextjs-development-environment-with-docker