Next.js・TypeScript・StoryBook・MUI・Recoilの環境をDockerで構築する方法

NextJS_Docker

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、Next.js・TypeScript・StoryBook・MUI・Recoilの環境をDockerで構築する方法について解説していきます。

Next.js・TypeScript・StoryBook・MUI・Recoilの環境をDockerで構築する方法

今回は、新規プロジェクトで、Next.jsで開発を進めることになったので、ベースはTypeScriptで、StoryBook・MUI・Recoilを追加した環境をDockerで構築していきます。

今回作成するNext.jsプロジェクトのディレクトリ構造

今回、作成するNext.jsプロジェクトのディレクトリ構造をtree -L 2 -aで、2階層まで確認すると次のとおりです。

tree -L 2 -a
.
├── Dockerfile
├── app
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .storybook
│   ├── README.md
│   ├── next-env.d.ts
│   ├── next.config.js
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── postcss.config.js
│   ├── public
│   ├── setup.sh
│   ├── src
│   ├── tailwind.config.js
│   ├── tsconfig.json
│   └── yarn.lock
└── docker-compose.yml

6 directories, 14 files

プロジェクト・ディレクトリの作成と移動

まずは、次のコマンドでプロジェクト・ディレクトリの作成と移動をします。

プロジェクト・ディレクトリ名は、自由に決めてください。

mkdir プロジェクト名 && cd プロジェクト名

Dockerfileを作成する

Dockerfileは、Dockerイメージをビルドするための設定ファイルです。

次のコマンドで、Dockerfileを作成して開きます。

touch Dockerfile && open Dockerfile

openしたDockerfileの内容は、次の内容をコピペしてください。

# Base_Image
FROM node:lts

# HostマシンからのAccessを受け付ける
ENV HOST 0.0.0.0

# Docker Cotainer上の作業ディレクトリ
WORKDIR /usr/src/app

Node.jsのランタイム環境を提供し、/usr/src/app ディレクトリにアプリケーションファイルをコピーするように指定しています。

  1. FROM コマンドは、ビルドするDockerイメージのベースとなるイメージを指定しています。
  2. WORKDIR コマンドは、コンテナ内で作業するディレクトリを /usr/src/app に設定しています。
    • WORKDIRで指定されたPathは、イメージ内でアプリケーションを実行するためのディレクトリとして使用されます。
    • 以降のRUNやCOPYコマンドで指定されたファイルやディレクトリは、このディレクトリ内にコピーされるようになります。
    • ちなみに、WORKDIRのディレクトリがContainerに存在しない場合は作成されます。

docker-compose.yml を作成する

docker-compose.yml は、Docker Composeを使用して、複数のDockerコンテナを定義し、それらを構成・連携するための設定ファイルです。

次のコマンドで、docker-compose.ymlを作成して開きます。

touch docker-compose.yml && open docker-compose.yml

openしたdocker-compose.ymlの内容は、次の内容をコピペしてください。

YAMLファイルは、JSONと違いコメントができるので、コメントを細かく記しています。

# versionは、3系
version: "3"
# Serviceを設定する
services:
  # Service名は、自由に決めていい
  frontend:
    # DockerfileまでのPath
    build: .
    # ホストマシン:コンテナ => ファイルを共有するための設定
    volumes:
      - ./app:/usr/src/app
      # - ./app:/usr/src/app/node_modules
    # ホストマシンPort番号:コンテナのPost番号
    ports:
      # Next.js との ポートフォワード
      - 3008:3000
      # StoryBook との ポートフォワード
      - 6006:6006
    # CLI画面の操作をできるようにする
    tty: true

今回のdocker-compose.yml の内容を解説します。

  1. version は、Docker Composeのバージョンを指定しています。
  2. services は、構築するサービスを動かすための各要素をネストさせて定義します。
    • 最初にサービス名を定義して、続けて設定内容を記述していきます。
  3. build コマンドは、Dockerfileを使用してイメージをビルドするためのPath設定を行います。
    • . は、Dockerfileがあるディレクトリ(Path)を指定しています。
    • 今回の場合、Docker Composeは現在のディレクトリのDockerfileを使用してイメージを構築します。
  4. volumes コマンドは、ホストマシンとDockerコンテナの間でファイルを共有するために使用されます。
    • ホストマシンの./app ディレクトリを、Dockerコンテナの /usr/src/app ディレクトリにマウントしています。
  5. ports コマンドは、Dockerコンテナとホストマシンのポートをマッピングするために使用されます。
    • 今回は、ホストマシンの3008番ポートをDockerコンテナの3000番ポート (Next.js) にマッピングしています。
    • また、ホストマシンの6006番ポートをDockerコンテナの6006番ポート (Storybook) にマッピングしています。
  6. tty コマンドは、Dockerコンテナ内でTTYを有効にするために使用されます。
    • 最後の行のTTYを有効にすることで、CLIの標準入出力がLockされずに機能して、コンテナ内でコマンドが実行できるようになります。

Next.js を installするディレクトリを作成する

docker-compose.yml に記載したとおり、ホストマシンの./app がMountされるので、

Next.js を install・ファイル共有する app ディレクトリを作成しておきます。

mkdir app

Next.js を installして、初期Set Upをする

次のコマンドを実行して、Next.jsをインストールします。

docker-compose run --rm frontend yarn create next-app . --ts

このコマンドは、Docker Composeを使用してフロントエンド環境で実行されるコマンドです。

コマンドの意味は、次のとおりです。

  1. docker-compose run: Docker Composeを使用して、指定したサービスを実行します。
    • この場合、frontendというサービスが実行されます。
  2. --rm: コマンドが完了した後、実行されたコンテナを削除します。
    • これにより、一時的なコンテナが残らずにきれいになります。
  3. frontend: 実行するサービスの名前です。
    • Docker Composeファイルにこの名前でサービスを定義しています。
  4. yarn create next-app .: カレントディレクトリ(.)にNext.jsアプリケーションの雛形を作成します。
  5. --ts: TypeScriptを使用してアプリケーションを作成します。

つまり、このコマンドはDocker Composeを使用してフロントエンド環境を実行し、Yarnを使用してTypeScript対応のNext.jsアプリケーションの雛形を作成します。

上記のコマンドで、Next.jsのインストールが始まります。

Next.jsのインストールの際には、いくつか質問があるので、それに答えていきます。

今回のプロジェクトで、聞かれた質問は、次のとおりです。

  1. Would you like to use ESLint with this project? … No / Yes
    • このプロジェクトで ESLint を使用しますか?
    • Yesを選択
  2. Would you like to use Tailwind CSS with this project? … No / Yes
    • このプロジェクトで Tailwind CSS を使用しますか?
    • Yesを選択
  3. Would you like to use src/ directory with this project? … No / Yes
    • このプロジェクトで src/ ディレクトリを使用しますか?
    • Yesを選択
    • src ディレクトリの作成はデフォルトでは、No になっていますが、 Yes を選択すると src ディレクトリの下に app ディレクトリが作成されます。
    • No の場合はプロジェクトディレクトリ直下に app ディレクトリが作成されます。
  4. Use App Router (recommended)? … No / Yes
    • App Router を使用しますか (推奨)?
    • Yesを選択
  5. Would you like to customize the default import alias? … No / Yes
    • デフォルトのインポートエイリアスをカスタマイズしますか?
    • Noを選択
    • (追記) Yes選択がおすすめ!
    • default import alias を利用するとコンポーネントを import する際に../../components/Userといったコードを@/components/Userというように記述することが可能になります。

CLIのログは、次のとおりです。

member-stack-search % docker-compose run --rm frontend yarn create next-app . --ts
[+] Running 1/0
 ⠿ Network member-stack-search_default  Created                                                                                                                                                                                          0.1s
[+] Building 2.9s (6/6) FINISHED                                                                                                                                                                                                              
 => [internal] load build definition from Dockerfile                                                                                                                                                                                     0.0s
 => => transferring dockerfile: 316B                                                                                                                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                                                                          0.0s
 => [internal] load metadata for docker.io/library/node:lts                                                                                                                                                                              2.7s
 => CACHED [1/2] FROM docker.io/library/node:lts@sha256:3f567a26b6b6d601fb2b168d4f987b50697617ead15bfc0e0152e600ac48d0fe                                                                                                                 0.0s
 => [2/2] WORKDIR /usr/src/app                                                                                                                                                                                                           0.0s
 => exporting to image                                                                                                                                                                                                                   0.0s
 => => exporting layers                                                                                                                                                                                                                  0.0s
 => => writing image sha256:93671d67ec468bcd00ab1b9c2de7b75e082d85013aed6fbf7301b7a0840cf2d1                                                                                                                                             0.0s
 => => naming to docker.io/library/member-stack-search-frontend                                                                                                                                                                          0.0s
yarn create v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...

success Installed "create-next-app@13.4.3" with binaries:
      - create-next-app
✔ Would you like to use ESLint with this project? … No / Yes
✔ Would you like to use Tailwind CSS with this project? … No / Yes
✔ Would you like to use `src/` directory with this project? … No / Yes
✔ Use App Router (recommended)? … No / Yes
✔ Would you like to customize the default import alias? … No / Yes
Creating a new Next.js app in /usr/src/app.

Using yarn.

これで、Next.jsプロジェクトはInstallできました。

コンテナ起動時に実行するShellスクリプトを作成する

次のコマンドで、ShellScriptのファイルを作成します。

cd app && touch setup.sh && open setup.sh

setup.sh には、次の内容をコピペしてください。

Docker Containerを起動する際に、自動で開発Serverを立てるように、yarn dev を実行するように設定しています。

set -eu

yarn && yarn dev

set -eu は、シェルスクリプトやシェルの動作を制御するための設定です。

それぞれのオプションの意味は、次のとおりです。

  1. -e オプション: エラーが発生した場合にスクリプトをすぐに強制終了します。
  2. -u オプション: 未定義の変数を使用しようとした場合にエラーを発生させます。

次は、setup.shを Docker Container起動時に動かすために、DockerfileにENTRYPOINTを追加します。

cd ../ && open Dockerfile

Dockerfileに、ENTRYPOINT のコマンド実行設定を追加してください。

ENTRYPOINT で指定されたコマンドは、Docker コンテナが起動されたときに実行されます。

# Base_Image
FROM node:lts

# HostマシンからのAccessを受け付ける
ENV HOST 0.0.0.0

# Docker Cotainer上の作業ディレクトリ
WORKDIR /usr/src/app

# Docker コンテナが起動されたときに実行されるコマンド
ENTRYPOINT ["sh", "./setup.sh" ]

MUI と styled-components を installする

Next.jsに追加していくパッケージは、appディレクトリに移動して、installします。

なので、まずは、次のコマンドで、appディレクトリに移動します。

cd app

次のコマンドで、MUIに関連するパッケージと styled-components を installします。

# yarn バージョン
yarn add @mui/material @mui/icons-material @emotion/react @emotion/styled @fontsource/roboto @mui/styled-engine-sc styled-components

# npm バージョン
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled @fontsource/roboto @mui/styled-engine-sc styled-components

次のコマンドで、Dev環境のみで使用する styled-components の型定義を installします。

# yarn バージョン
yarn add --dev @types/styled-components

# npm バージョン
npm install --save-dev @types/styled-components

Recoil を installする

次のコマンドで、Recoilと、Dev環境のみで使用する型定義を installします。

# yarn バージョン
yarn add recoil && yarn add -D @types/recoil

# npm バージョン
npm install recoil && npm install --save-dev @types/recoil

StoryBook を installする

次のコマンドで、StoryBookを installします。

npx storybook init

Next.js のpackage.json を確認する

Next.js のpackage.json を確認すると、recoil@mui styled-components

Dev環境専用にstorybook や、型定義ファイルが追加されていることがわかります。

{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "@emotion/react": "^11.11.0",
    "@emotion/styled": "^11.11.0",
    "@fontsource/roboto": "^5.0.1",
    "@mui/icons-material": "^5.11.16",
    "@mui/material": "^5.13.2",
    "@mui/styled-engine-sc": "^5.12.0",
    "@types/node": "20.2.3",
    "@types/react": "18.2.6",
    "@types/react-dom": "18.2.4",
    "autoprefixer": "10.4.14",
    "eslint": "8.41.0",
    "eslint-config-next": "13.4.3",
    "next": "13.4.3",
    "postcss": "8.4.23",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "recoil": "^0.7.7",
    "styled-components": "^5.3.11",
    "tailwindcss": "3.3.2",
    "typescript": "5.0.4"
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^7.0.17",
    "@storybook/addon-interactions": "^7.0.17",
    "@storybook/addon-links": "^7.0.17",
    "@storybook/blocks": "^7.0.17",
    "@storybook/nextjs": "^7.0.17",
    "@storybook/react": "^7.0.17",
    "@storybook/testing-library": "^0.0.14-next.2",
    "@types/recoil": "^0.0.9",
    "@types/styled-components": "^5.1.26",
    "eslint-plugin-storybook": "^0.6.12",
    "storybook": "^7.0.17"
  }
}

docker-composeでDockerfileからimageをビルドする

今は、appディレクトリにいると思うので、上の階層に戻ります。

app % cd ../

次にDocker image を作成するために、docker-compose buildを実行します。

docker-compose buildコマンドは、Dockerファイルから imageを作成してくれるコマンドです。

コンテナは作成しないので、注意です。

docker-compose build

このコマンドを実行すると、Dockerfileに従って各サービスのDockerイメージがビルドされ、イメージ名とタグ名が作成されます。

docker image ls で、buildされたimageを確認すると次のとおりです。

docker image ls
REPOSITORY                         TAG       IMAGE ID       CREATED          SIZE
member-stack-search-frontend       latest    0c4b7d7ee334   14 seconds ago   946MB

Docker コンテナを実行する

Docker Image の作成を確認したら、Docker Container を実行します。

次のコマンドで、Docker Composeファイルに定義されたサービスをバックグラウンドで起動できます。

docker-compose up -d

docker-compose up -d コマンドは、Docker Composeファイルに定義されたサービスをバックグラウンドで起動するために使用されます。

このコマンドを実行すると、Docker Composeファイルに定義されたすべてのサービスが起動し、Dockerイメージが必要に応じて自動的にダウンロードされます。

最終的な動作確認

Dockerコンテナの起動状況はdocker container psで確認できます。

localhost: 3008から Containerの 3000番Portにコネクションがあることがわかります。

docker container ps
CONTAINER ID   IMAGE                          COMMAND                  CREATED          STATUS          PORTS                    NAMES
2bc3fe4670cc   member-stack-search-frontend   "sh ./setup.sh"          23 seconds ago   Up 21 seconds   0.0.0.0:3008->3000/tcp   member-stack-search-frontend-1

今回は http://localhost:3008/ にアクセスして、次のような Next.js App が立ち上がっていれば成功です。

volume マウントによる Docker ContainerとLocalのファイル共有もしているので、

VSCodeでappのディレクトリの中を確認すると、次のような Nuxt.jsのプロジェクトができているはずです。

Docker Composeで建てた Docker Container を停止 & 削除する

docker-compose down コマンドを使用して、Docker Composeで建てたすべてのコンテナを停止し、削除することができます。

docker-compose down

Storybook の環境を立ち上げる方法

Next.js の Docker Container の Bash を実行するために次のコマンドを実行します。

docker container exec -it member-stack-search-frontend-1 /bin/bash

Docker Container の Bash (#) に入ったら、Storybook を立ち上げる次のコマンドを実行します。

# yarn バージョン
yarn storybook

# npm バージョン
npm run storybook

コマンドを実行すると、次のように、Storybook の Serverが立ち上がります。

http://localhost:6006/ にアクセスして、次のような StorybookのTop画面が立ち上がっていれば成功です。

Twitterやってます!Follow Me!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

React関連の書籍

参考・引用

  1. Next.js + TypeScript + Dockerを使った環境構築
  2. 【Storybook × Next.js】Next.jsで始めるStorybookの始め方
  3. 進化が止まらない!Next.js13の基本機能をしっかり理解しよう

プログラミング学習・エンジニア転職関連の情報

自宅で現役エンジニアから学べる『TechAcademy』 (エンジニア転職保証)

『GEEK JOBキャンプ』スピード転職コース(無料)

【IT道場】入校時0円! 就職目的プログラミングスクール

エンジニア転職なら100%「自社開発」求人に強い【クラウドリンク】

『techgym』 (Python特化・無料)

最近の投稿