【Next】Next.js+TypeScript+Express+JestをDocker環境で構築する
今回、Next.jsの勉強を始めようと思い、Dockerにて開発環境の構築を行った。
なお、実装したサンプルコードは GitHub に公開している。
本記事では、ポイントだけを抜粋して説明するため、実際にコード全体を確認する場合は GitHub を参照ください。
環境構築の流れ
Next.jsで必要とされる環境条件は以下となっている。
Dockerは事前にPCにインストールされていることを前提とし、以下の手順で行った。
- Dockerfile / docker-compose.ymlの作成
- Dockerイメージのビルド
- create-next-app を実行
- コンテナの起動
- Expressのインストール
1. Dockerfile / docker-compose.ymlの作成
まずは、作業ディレクトリに、以下のディレクトリ構成を作成する。
nextjs-ts-jest-express |-- docker |-- Dockerfile |-- docker-compose.yml
Dockerfile作成
Dockerfileとは、Docker上で動作させるコンテナの構成情報を記述したファイルである。
Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
主に、以下を使用する。
- FROM:ベースとなるimageの指定
- WORKDIR:コンテナ内の作業ディレクトリ指定
- RUN:コマンドの実行
- COPY:ローカルからdocker imageへのファイルの転送
From node:14-alpine WORKDIR /usr/src/app
今回は、Node.jsイメージの最新バージョン(v14)で、かつ超軽量のalpineイメージをビルドする。
docker-compose.yml作成
Docker composeは複数のコンテナをまとめて管理するためのツールである。
今回作成するのはNode.jsをベースイメージとしたコンテナのみであるが、 docker run
コマンドで毎回オプションをつけて指定するよりも、 docker-compse up
のみで実行したいため作成を行った。
Docker Compose — Docker-docs-ja 17.06 ドキュメント
version: '3' services: nextjs: build: ./docker/ container_name: nextjs-ts-jest-express volumes: - ./:/usr/src/app command: "yarn dev" ports: - "4001:3000"
2. Dockerイメージのビルド
$ docker-compose build
3. create-next-app を実行
$ docker-compose run --rm nextjs yarn create next-app --example with-typescript-eslint-jest app
create-next-app
を実行することで、nextをインストールすることができる。
nextには様々なサンプルが用意されているので、選択してインストールすることができる。本当に感謝しかない。
今回、プロジェクト名を「app」とし、templateを「with-typescript-eslint-jest」とした。 インストール完了後、以下のようなフォルダ構成となる。
nextjs-ts-jest-express |-- docker |-- Dockerfile |-- docker-compose.yml |--app |-- (Next.jsのサンプルプログラム)
4. コンテナの起動
コンテナを起動する前に、docker-compose.yml を一部訂正する。
volumes: (変更前)- ./:/usr/src/app (変更後)- ./app:/usr/src/app
こうすることで、ローカルの/appをルートディレクトリとして操作ができるようになる。
$ docker-compose up
http://localhost:4001/ にアクセスすることで起動を確認することができる。
5. Expressのインストール
$ docker-compose run --rm nextjs yarn add express
server/index.jsのファイルを作成し、package.jsonを一部変更する。
const next = require('next') const express = require('express') const port = parseInt(process.env.PORT || '3000', 10) const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { const server = express() server.get('*', (req, res) => { return handle(req, res) }) server.listen(port, (err) => { if (err) throw err console.log(`> Ready on ${process.env.CLIENT_URL || `http://localhost:${port}`}`) }) }) .catch((ex) => { console.error(ex.stack) process.exit(1) })
{ "scripts": { "dev": "node server/index.js", "build": "next build", "start": "cross-env NODE_ENV=production node server/index.js" }, }
docker-compose up
で再度コンテナを起動することで、Expressを使った表示を確認することができた。
Next.jsはテンプレートが豊富で簡単に様々な開発環境を簡単に用意することができることがわかった。
それでは、ステキな開発ライフを。
おまけ
node-imageにはyarnがすでにインストールされている
From node:14-alpine RUN npm install -g yarn
Yarnをインストールしようとすると、エラーが表示された。
npm ERR! File exists: /usr/local/bin/yarn npm ERR! Remove the existing file and try again, or run npm
nodeのコンテナには既にインストール済みなので、再インストールしようとすると、エラーが表示された。
docker-composeを使わない場合の実行方法
Dockerイメージのビルド
build — Docker-docs-ja 17.06 ドキュメント
$ docker build -t nextjs ./docker/
Dockerコンテナの起動
run — Docker-docs-ja 17.06 ドキュメント
$ docker run --name nextjs-ts-jest-express -v ./:/usr/src/app -p 4001:3000 nextjs