【環境構築】NestJS+Next.js+TypeScript+Dockerの環境構築ハンズオン

個人開発しよっかな〜とお友達のエンジニアとお話ししていて、「フロントエンドならNestJSも使ってTypeScriptでやりなよ！ハンズオンしたるで！」とハンズオンで教えていただいたので🙏

## 1.Dockerの環境構築を行う
### Docker Desktop for Macのダウンロード
Docker初心者なのでDocker Desktop for Macというツールを使用します。

https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/

![スクリーンショット 2022-06-07 9.11.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/c5def82d-f1be-333d-55c5-f422409f5e10.png)

Intel チップの Mac ・ Apple チップの Macとあるので、自身のmacのスペックに合ったものをダウンロードしましょう💡

Docker.dmgのダウンロードが完了したら、アプリケーションフォルダへの移動を行います。

アプリケーションフォルダからDockerアイコンを選択し、立ち上がったら準備は完了です。

### nest-nextディレクトリの作成
ターミナルでコマンドを実行し、ディレクトリを作成していきます。

```
// 1. Users/Macでのユーザー名のディレクトリに移動
cd ~

// 2. 移動できたか確認
pwd
(pwdを打ち込んだ後に、Users/Macでのユーザー名/と表示されたらOK)

// 3. ディレクトリの作成
mkdir nest-next

// 4. 3で作ったディレクトリに移動する
cd nest-next 
```

## docker-compose.ymlファイルを作成する

ディレクトリが作成・移動ができたら、ここで`docker-compose.yml`ファイルを作成していきます。

まずは、以下のコマンドを実行してファイルを作成していきましょう。
```
touch docker-compose.yml
```

ディレクトリを見ると`docker-compose.yml`という中身が何も書かれていないファイルが作成されます。

このファイルにDockerの設定を書いていきます。
まずはバックエンドで使用するNestJSから記述していきましょう。

```yml
version: "3.7"

services:

  backend:
    build:
      context: .
      dockerfile: ./docker/backend/Dockerfile
    tty: true
    volumes:
      - type: bind
        source: ./backend
        target: /api
    ports:
      - "3000:3000"
```

一旦バックエンドの`docker-compose.yml`が完成しました🎉

## フレームワークのインストール＆Dockerファイルの作成
### バックエンド編: Dockerファイルの作成

今回は、フロントエンド・バックエンドを別々に作成するため、それぞれfrontendとbackendというディレクトリを作成します💡

また、NestJSのインストールも一緒に行ってしまいます。

前回書いた`docker-compose.yml`の中にある、
- `dockerfile: ./docker/backend/Dockerfile`

で指し示しているディレクトリを作成しましょう。

ターミナルでコマンドを実行し、ディレクトリを作成していきます。

```
mkdir docker
cd docker
mkdir backend
```

`/docker/backend/`ディレクトが作成できたため、このディレクトリの中に入れるDockerfileを作成していきます。

pwdコマンドで現在いるディレクトリを確認し、必要に応じて`cd backend`で移動後、Dockerfileを作成します。

```
cd backend
touch Dockerfile
```

Dockerfileが作成されたら、以下の内容をDockerfileに記述しておきます。

```dockerfile
FROM node:16.14.2-alpine
WORKDIR /api
CMD ["npm", "run", "start"]
```

Dockerfileに書いたのはdockerを立ち上げる際に実行されるnpmコマンドなどが記述されています。


### バックエンド編: NestJSのインストール
ここまでできたら、NestJSのインストール・実行を行います。

まず`nest-next`ディレクトリに戻った後インストールを行います。

```
// nest-nextに戻る
cd ../..

// NestJS・TSのインストール
npm i -g @nestjs/cli
npm i -g typescript tsc-watch
npm i @nestjs/common @nestjs/core reflect-metadata @nestjs/platform-express
npm i --save-dev @types/node

// NestJSの作成
nest new
// プロジェクト名なんぞ？と聞かれるのでbackendと入力
? What name would you like to use for the new project? backend
// 今回はnpmを選択
? Which package manager would you ❤️  to use? npm
```
インストールを行い、「Thanks for installing Nest🙏」と出ればインストールが完了です。
![スクリーンショット 2022-07-02 19.26.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/e8e79c08-ef49-ef41-460c-a3a78bf0ac1c.png)

ここで一度dockerを起動してみましょう。以下のコマンドを入力します。
```
docker compose up -d
```
コマンドの実行が完了後、正しく起動しているか以下のコマンドで確認します。

```
docker compose ps
```

STATUSの下に「running」とあったら正しく起動しています。
![スクリーンショット 2022-07-02 19.42.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/d090d768-024c-1198-3be0-7a9fcd3842ea.png)


ブラウザでも`http://localhost:3000/`を打ち込んでみて、「Hello World!」の文字が確認できたらバックエンド編は完了です🎉

![スクリーンショット 2022-07-02 19.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/e9fb03b6-b57c-b30a-640f-d8beb027dc99.png)


### フロントエンド編: Dockerファイルの作成
バックエンド編と手順はほぼ一緒なのですが、続いてフロントエンド編もやっていきましょう！

一旦、dockerは落としておきましょう。以下のコマンドで落とせます。

```
docker compose down
```

dockerを落としたら、dockerディレクトリ内に移動してfrontendディレクトリとDockerfileを作成します。

```
cd docker
mkdir frontend
cd frontend
touch Dockerfile
```

新しく作成できた`Dockerfile`に以下を追記します。
```dockerfile
FROM node:16.14.2-alpine
EXPOSE 3333
WORKDIR /app

RUN apk update && \
    apk upgrade

CMD ["npm", "run", "dev"]
```

### フロントエンド編: docker-compose.ymlファイルに追記

`docker-compose.yml`にもフロントエンドの記述を行います。
```yaml
version: "3.7"

services:
  backend:
    build:
      context: .
      dockerfile: ./docker/backend/Dockerfile
    tty: true
    volumes:
      - type: bind
        source: ./backend
        target: /api
    ports:
      - "3000:3000"

  // 以下、追記箇所
  frontend:
    build:
      context: .
      dockerfile: ./docker/frontend/Dockerfile
    tty: true
    volumes:
      - type: bind
        source: ./frontend
        target: /app
    ports:
      - "3333:3333"
```

### フロントエンド編: Next.jsのインストール
`nest-next`ディレクトリに戻り、Next.jsのインストールを行います。

```
// nest-nextディレクトリに戻る
cd ..

// Next.js+TSのインストール
npx create-next-app@latest --ts

// プロジェクト名なんぞ？と聞かれるのでfrontendと入力
✔ What is your project named? … frontend
```

「Success! Created frontend at　/Users/ユーザー名/nest-next/frontend」と表示されたらインストール完了です。

Next.jsのデフォルトのポート番号が「3000」になってしまっているので、`package.json`を少し変更します。

```
  "scripts": {
    // next devから「next -p 3333」に変更する
    "dev": "next -p 3333",
  }
```

ここで一度dockerを起動してみましょう。以下のコマンドを入力します。
```
docker compose up -d
```
コマンドの実行が完了後、正しく起動しているか以下のコマンドで確認します。

```
docker compose ps
```

STATUSの下に「running」とあったら正しく起動しています。
![スクリーンショット 2022-07-02 20.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/68350781-b244-3151-5566-3feaf367373d.png)


ブラウザでも`http://localhost:3333/`を打ち込んでみて、「Welcome to Next.js!」の文字が確認できたらフロントエンド編が完了です。🎉

![スクリーンショット 2022-07-02 20.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/0766856e-b041-8106-361a-4a11edd6b684.png)


### 参考にさせていただいた記事
https://zenn.dev/senri/articles/331162304a78e0

https://qiita.com/Gma_Gama/items/def2643aaa7f5f7af41d