NextJsとNestJsをDockerで立ち上げる

あくまでもDockerのハンズオンなので別に何でもいいのだが、どうせならということで、次に考えている構成でやってみることにした。

ちなみに【環境構築】NestJS+Next.js+TypeScript+Dockerの環境構築ハンズオンに倣うようにすすめていくので、こちらの記事を参考にした方がいいかもしれない。

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

プロジェクトのルートでdocker-compose.ymlファイルを作成する。そのために下記コマンドを実行する。

touch docker-compose.yml

実行後、docker-compose.ymlという名前の空ファイルができていることを確認することができる。

このファイルにDockerの設定を書いていく。

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が作成できたらしい。

まずはバックエンドのみで起動するためフロントエンドの設定は書かない。

バックエンドの設定

それではバックエンド、つまりNestJs側の設定をすすめていく。

Dockerファイルの作成

設定ファイルに書いた

dockerfile: ./docker/backend/Dockerfile

で指示したディレクトリを作成する。

mkdir docker
cd docker
mkdir backend

作成したディレクトリにDockerfileを作成する。

cd backend
touch Dockerfile

作成が完了したら以下の内容を記述する。

FROM node:16.18.0
WORKDIR /api
CMD ["npm", "run", "start"]

ちなみにnodeのバージョンは参考にした記事の通りではなく、なんとなく現在他案件で使用しているバージョンにしてみた。

↓のちに下記に変更した(よくわからないけど)。

FROM node:16-alpine3.16

これでDocker側の設定は完了。

NestJsをインストールする

次にNestJsをインストールする。

cd ../..

プロジェクトのルートに戻り、nest newを実行※1する。

nest new
? What name would you like to use for the new project? backend
? Which package manager would you ❤️  to use? npm

上記のように2つ聞かれるので、1つ目はbackend、2つ目は任意のpackage managerを選択する。

Thanks for installing Nest 🙏

が表示されればインストール完了。

※1 @nestjs/cliをインストールしたことない人、つまり初めての人はnest new の前に下記コマンドを実行する。

npm i -g @nestjs/cli

バックエンドを起動する

まずはDockerを起動する。

docker compose up -d

色々処理が走り終わった後にhttp://localhost:3000/にアクセスできれば起動が成功している。

フロントエンドの作成

次にフロントエンドの作成をするので、いったんDockerは落としておく。

docker compose down

Dockerファイルの作成

cd docker
mkdir frontend
cd frontend
touch Dockerfile

上記コマンドで作成したDockerfileに以下を追記する

FROM node:16.18.0
EXPOSE 3333
WORKDIR /app

RUN apk update && \
    apk upgrade

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

docker-compose.ymlファイルに追記

バックエンドの環境構築の際に書いたdocker-compose.ymlにフロントエンドの設定を追記する。

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"

NextJsをインストールする

プロジェクトのルートに戻りNextJsをインストールする。

$ npx create-next-app@latest --typescript
Need to install the following packages:
  create-next-app@13.1.2
Ok to proceed? (y) y
√ What is your project named? ... frontend
√ Would you like to use ESLint with this project? ... No / Yes
√ Would you like to use `src/` directory with this project? ... No / Yes
√ Would you like to use experimental `app/` directory with this project? ... No / Yes

なんか今まで聞かれたことない質問をされたが(Next13のせいか)、今回の肝となるのはProject Namefrontendと答えればいい。

…全部Yesにするべきだったかもしれない。が、今回は気にすることないのでそのまま進める。

次にNextpackage.jsonのポートを3333に変更する。

"scripts": {
    "dev": "next -p 3333",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
}

サーバーを起動する

docker compose up -d

コケたので調べたら

// 以下、追記箇所

が原因だったので、削除で再実行。

またエラーが出たので、調査すると

RUN apk update && \
    apk upgrade

どうやらフロントのDockerfileでエラーが出ていたので、上記該当行削除して再実行したら無事にDockerが起動した。

ちなみに

RUN apk update && apk upgrade --no-cache

でも動作した。ただこのコマンド何をしているかはわからない。

http://localhost:3333/にアクセスするとブラウザでも動いていることが確認できた。

とりあえずスタートラインに立てた。

立って気づいたけど、ホットリロードが効かない。これはまた別で調査する。今回はともかくDockerで基本的な環境構築まで。