エンジニア管理ツールでも作る②Next.js環境用意

# 前回
構想を練って下準備までしました。

https://qiita.com/k-jimon/items/6179df0f317b30573879

# 今回の目標
DockerでNext.js環境を作る

# Dockerファイル用意
```dockerfile
# front/Dockerfile
FROM node:22

ENV NODE_ENV=development

WORKDIR /app
```
Dockerfileはこちら。
nodeのバージョンは22を使用しています。


```yml
# docker-compose.yml
version: '3'
services:
  front:
    build: front
    image: sk-front
    tty: true
    volumes:
      - ./front:/app
    ports:
      - "3001:3000"
```
docker-compose.ymlはこちら。
先ほどのDockerfileをビルドして、`sk-front`という名前のDockerイメージとして保存します。

`tty: true`としておくと、コンテナがタスクを実行し終えても残ってくれます。
今のイメージは「Node環境を作る」がタスクなので、これがないと「Node環境作りました。では！」と消えていきます。

`volumes`でコンテナの中と同期するファイルを設定します。
今回は`front`ディレクトリの中身全てを、コンテナ内の`/app`ディレクトリと同期させています。
`volumes`の設定の仕方は色々あるんですが、今回はバインドマウントってやつです。

https://qiita.com/P-man_Brown/items/30fba7bb265a525c77ad

`ports`はNext.jsが3000番ポートを使用するので、コンテナの3000ポートとホスト(私のPC)の3001ポートを繋げています。
ポート3000はよく被るからちょっとずらしただけで、別にホストの3000ポートに繋げても構いません。

## Dockerコンテナ立ち上げ

ここまでできたらコンテナを立ち上げていきます。
```shell
docker compose up -d
```
`docker compose up`でサービス(コンテナ)が立ち上がります。
初めての場合、build(イメージの作成)も一緒にやってくれます。
逆にいうと次回からは勝手にbuildしてくれないので、Dockerfileを編集したら
```shell
docker compose build
```
をしましょう。

`-d`はデーモンのdです。
裏で動くようなプロセスのことをデーモンといいます。悪魔ではないです。
これをつけないとターミナルがこのプロセスで占領されて次のコマンドが打てなくなります。(Ctr+Cで止まります)

```shell
docker compose ps
```
でコンテナを状態を確認できます。

```
NAME            IMAGE      COMMAND                   SERVICE   CREATED      STATUS         PORTS
skill-front-1   sk-front   "docker-entrypoint.s…"   front     4 days ago   Up 8 seconds   0.0.0.0:3001->3000/tcp
```
`STATUS`が`UP`になっていても「コンテナが立っている」というだけで「準備OK」という意味ではないので注意が必要です。
まだ必要なものをダウンロードしている最中かもしれません。

そんな時は
```shell
docker compose logs -f front
```
を実行してあげると、ログを眺めることができます。
流れゆくログが止まったら大体準備OKと考えていいです。
`-f`がログをリアルタイムで見るためのオプションです。
Ctr+Cで止まります。


## Dockerコンテナに入る
```shell
docker compose exec front bash
```
`exec`はコンテナに対してコマンドを送信することができます。
上記コマンドでは`front`コンテナに対して`bash`コマンドを実行しています。
これでコンテナ内の`bash`を起動して、対話形式でコマンドを実行できるようになります。
`exit`やら`Ctr+D`で抜けられます。

## Next.jsインストール
公式ドキュメントのまんま進めます。

https://nextjs.org/docs/getting-started/installation

```terminal
npx create-next-app@latest
```

```terminal
What is your project named? my-app
Would you like to use TypeScript? No / *Yes
Would you like to use ESLint? No / *Yes
Would you like to use Tailwind CSS? No / *Yes
Would you like to use `src/` directory? *No / Yes
Would you like to use App Router? (recommended) No / *Yes
Would you like to customize the default import alias (@/*)? *No / Yes
```

`my-app`ディレクトリが作成されて、その中に色んなファイルが置かれていと思います。
今回は`/app`をディレクトリをワーキングディレクトリにしたいので、`my-app`ディレクトリにはご退場願います。

```terminal
mv ./my-app/* .
mv ./my-app/.eslintrc.json .
mv ./my-app/.gitignore .
rm -r ./my-app
```

## Next.js起動
開発モードで起動します。
```
npm run dev
```

```
> app@0.1.0 dev
> next dev
  ▲ Next.js 14.2.3
- Local:        http://localhost:3000

✓ Starting...
```
みたいなログの通り、ポート3000で起動します。
ここでのlocalhostは`front`コンテナのlocalhostのことです。

当分前にdocker-compose.ymlにて
```yml    
    ports:
      - "3001:3000"
```
と設定した通り、コンテナの3000とローカルPCの3001が繋がっています。

`localhost:3001`にアクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537927/6951d8ea-7c1c-f0dd-96bd-5494b61f9bbc.png)

ね、簡単でしょう？

https://dic.nicovideo.jp/a/%E3%81%AD%E3%80%81%E7%B0%A1%E5%8D%98%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%3F


# docker-compose.yml修正
```yml
# docker-compose.yml
version: '3'
services:
  front:
    build: front
    image: sk-front
    volumes:
      - ./front:/app
    ports:
      - "3001:3000"
    command: 'npm run dev'
```
最後にdocker-compose.ymlを少し修正しておきます。


`command: 'npm run dev'`を追加しました。
これで`docker compose up -d`をしたとき、このコマンドを実行してくれます。
つまりこのコンテナのタスクは「Node環境を作る」から「Node環境を作ってNext.jsサーバーを起動し続ける」になりました。
Next.jsサーバーが終了しない限り、このコンテナは残り続けてくれるので`tty: true`は不要になります。


## 次回
Python(Flask, Gunicorn)の環境構築

https://qiita.com/k-jimon/items/2179afaa50d0df1cde9a