Docker + Next.js ローカル開発環境をテンプレート化した

# はじめに
Next.jsの学習や検証用に色々と使いまわせる開発環境がほしかったので、
Docker Composeで簡易的なローカル開発環境をGitHubのテンプレートリポジトリ化しました。

今回作成したGitHubのリポジトリをテンプレートとして、
自分の新しいリポジトリをいくつも作成できるので、学習用やら検証用に使い捨てもできて便利:bulb:

- 使い方は[こちら](#使い方)
- 環境構築した手順などは[こちら](#環境構築した手順とざっくり解説)

## テンプレートリポジトリとは

GitHubのドキュメントは[こちら](https://docs.github.com/ja/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template)

**既存のリポジトリと同じディレクトリ構造とファイルを持つ新しいリポジトリを生成できます。**


フォークと似てますが、いくつか違いがあります。

- フォークには親リポジトリのコミット履歴全体が含まれるが、テンプレートから作成されたリポジトリは単一のコミットから始まる

- フォークへのコミットはコントリビューショングラフに表示されないが、テンプレートから作成されたリポジトリへのコミットはコントリビューショングラフに表示される

- フォークは既存のプロジェクトにコードを提供するための一時的な方法になる可能性があるが、テンプレートからリポジトリを作成すると、新しいプロジェクトがすぐに開始される


# リポジトリ
https://github.com/mizu0715/docker-next.js

こちらのテンプレートリポジトリから自分用のリポジトリを作成して、セットアップすればサクっと使えると思います:+1:

環境構築時点での各種バージョンはこちら
```
  "dependencies": {
    "@types/node": "18.11.9",
    "@types/react": "18.0.25",
    "@types/react-dom": "18.0.9",
    "eslint": "8.28.0",
    "eslint-config-next": "13.0.4",
    "next": "13.0.4",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "typescript": "4.9.3"
  }
```

# 使い方
#### 前提条件
- Gitインストール済み
- GitHubアカウント作成済み
- Docker Desktop for Mac(Windows)インストール済み

#### テンプレートから自分用のリポジトリ作成
リポジトリの[[Use this repository]](https://github.com/mizu0715/docker-next.js/generate)をクリックして、自分用のリポジトリを作成

- 同じディレクトリ・ファイル構造のリポジトリが作成される
- 作成時に「Include all branches」にチェックを入れなければコミット履歴も全て自分のコミットのみ

![スクリーンショット 2022-11-23 14.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122907/e17a0c69-3a22-8811-5055-506a99646d03.png)

#### Git clone
作成したリポジトリをローカルにclone
```zsh
% git clone https://github.com/作成した自分のリポジトリ
```

#### Docker環境の作成・起動
バックグランドで実行したい場合は`-d`オプションで
```zsh
% cd 作成したプロジェクトのルートディレクトリ
% docker-compose up -d
```

#### 依存パッケージのインストール
Next.jsプロジェクトにnode_modulesのインストールが必要

```zsh
% docker-compose exec app yarn

# or

% docker-compose exec app bash
> yarn
```

#### Next.jsの開発サーバを起動
```zsh
% docker-compose exec app yarn dev

# or

% docker-compose exec app bash
> yarn dev
```

#### 画面表示
ブラウザで`localhost:3000`を開けば画面が表示されます:raised_hands:

![スクリーンショット 2022-11-23 3.13.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122907/dfab30e5-3c40-7e17-f9ee-fa8dd9d206d3.png)

あとはご自由にお使いください!

# 環境構築した手順とざっくり解説
各種細かいところは、詳細に解説してくださっている記事もたくさんあると思いますので、そちらご参照ください:bow:

## ディレクトリ・ファイル構成
以下のディレクトリ・ファイルを作成
```
.
├── node
│   └── Dockerfile　
├── src
└──　　docker-compose.yml
```

## Dockerfile
nodeコンテナ用の設定ファイル
```Dockerfile
FROM node:lts-bullseye-slim
WORKDIR /app
```

> FROM node:lts-bullseye-slim

[DockerHub](https://hub.docker.com/)から「[node:lts-bullseye-slim](https://hub.docker.com/_/node/tags?page=1&name=lts-bullseye-slim)」のイメージを取得

イメージの名称の各意味はこんな感じ
|node:|lts|bullseye|slim|
|:----|:----|:----|:----|
|nodeの|長期間サポートされるバージョンで|ベースとなるOSがDebianのv11で |不要なパッケージを除いた軽量なイメージ |

bullseyeはDebianのバージョンの名称で、バージョンごとになんか色々カッコイイのがついている
|名称|バージョン|
|:----|:----|
|bullseye|v11| |
|buster|v10|
|stretch|v9|

> WORKDIR /app

コンテナ内の作業ディレクトリを指定、存在しない場合は自動で作成される
```zsh
% docker compose exec app bash
```
上記コマンドで、コンテナ内に入ると`/app`にいることになる
```
root@XXXXXXXX:/app# pwd
/app ← 現在のパス
```

## docker-compose.yml
Docker Composeの設定ファイル
```yml
version: "3"
services:
  app:
    build:
      context: .
      dockerfile: ./node/Dockerfile
    tty: true
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    # If you want to run `yarn dev` at docker compose startup
    # command: sh -c "yarn dev"
```

> version: "3"

docker-composeで使用するバージョン

> services:

複数サービスの定義をしていく、今回は1つのみ

> app:

サービス名、今回は`app`とした

> build:
> 　context: .
> 　dockerfile: ./node/Dockerfile

contextは`docker build`を実行する時のワーキングディレクトリ
[こちらの記事](https://qiita.com/sam8helloworld/items/e7fffa9afc82aea68a7a)に詳しく書いてくださっており参考になります。


dockerfileは`Dockerfile`のパスを指定


> tty: true

dockerを起動した際に、サーバの起動などずっとフォアグラウンドで実行しているプロセスがないと、起動してすぐにコンテナが停止してしまう

コンテナを起動したままにするために設定

> volumes:
> 　- ./src:/app

ホスト側のディレクトリ`./src`を、コンテナのディレクトリ`/app`にマウント（バインドマウント）
`src`ディレクトリの中に後ほどNext.jsをインストールする

> ports:
> 　- "3000:3000"

「ホスト側のポート：コンテナ側のポート」

Next.jsの開発サーバのポートはデフォルトで3000なので、コンテナ側のポート(右側)は3000
今回はホスト側(左側)も3000で統一して`localhost:3000`で画面が開けるように設定

ホスト側を3001などに設定した場合は`localhost:3001`で画面が開ける

## src
Next.jsを後ほどインストールするための空のディレクトリ

## Next.jsのインストール
ファイル・ディレクトリの事前準備ができたら、Dockerを起動しNext.jsをインストールする
```bash
# Docker環境作成・起動
% docker-compose up

# コンテナに入る
# WORKDIRで設定した/appにいる状態
% docker-compose exec app bash

# Next.jsインストール
> yarn create next-app . --typescript

```

`docker-compose.yml`の設定で、
コンテナ内の`app`ディレクトリはホスト側の`src`ディレクトリとマウントされているため、
`app`ディレクトリ内にインストールしたNext.jsがホスト側の`src`ディレクトリ上でも同期されている
　

> yarn create next-app . --typescript

`--typescript`オプションでTypeScritptプロジェクトとしてインストール

また、「.」でカレントディレクトリ内にファイルを展開している
```
.
├── node
│   └── Dockerfile　
├── src
│     └── [Next.jsのファイル]
└──　　docker-compose.yml
```
　
「.」を指定しない場合は、
コマンド実行時にプロジェクト名が対話形式で聞かれ、入力したプロジェクト名でディレクトリが作成されてNext.jsがインストールされる

```
.
├── node
│   └── Dockerfile　
├── src
│     └── [プロジェクト名]
│             └── [Next.jsのファイル]　　
└──　　docker-compose.yml
```

## 画面表示確認
```
yarn dev
```
あとは`yarn dev`して`localhost:3000`で画面が開けるか確認


以上で完了！