Next.js × Nest.jsの環境をDockerで作成する
はじめに
フロントエンドをNext.js、バックエンドをNest.jsで作成し、Dockerで環境構築します。
- node
20.9.0
- next.js
14.2.11
- nest.js
10.0.0
プロジェクトを作成
任意の開発ディレクトリでプロジェクト用のディレクトリを作成します。
mkdir next-nest-dev
cd next-next-dev
フロント側をNext.jsで作成
Next.jsのフロント環境をcreate-next-app
を使って作ります。
npx create-next-app front
対話形式で選択できる初期設定は好みですが、今回は以下の通り選択しました。
✔ 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
Success!
と表示されたら、/front
に移動してlocalhost
を立ち上げます。
cd front
yarn
yarn dev
localhost:3000
にアクセスして表示されていればOKです。
バックエンド側をNest.jsで作成
同様にしてバックエンド側も作成していきます。
Nest.jsのCLIのインストールがまだの方はnpm i -g @nestjs/cli
でインストールしてください。
Nest.jsの雛形を作成します。
nest new back
/back
にファイルが出力されたら/front
のポートとバッティングしないようにポートを5000
に変更しておきます。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
- await app.listen(3000);
+ await app.listen(5000);
}
bootstrap();
localhost
が立ち上がるか確認します
yarn run start
localhost:5000
で**Hello, World!**が確認されたらOKです。
Dockerで開発環境を立ち上げる
プロジェクトルートにdocker-compose.yml
を作成します。
version: "3.8"
services:
api:
build:
context: ./docker/back
dockerfile: Dockerfile
volumes:
- ./back:/app
ports:
- "5000:5000"
networks:
- app-network
front:
build:
context: ./docker/front
dockerfile: Dockerfile
volumes:
- ./front:/app
ports:
- "3000:3000"
networks:
- app-network
networks:
app-network:
driver: bridge
フロントエンドとバックエンドをそれぞれ立ち上げるためにDockerfile
を作成します。
/docker
ディレクトリを作成し、その中に/front
、/back
を作成。その中にDockerfile
を作成します。
├── front
├── docker
│ ├── front
│ │ └── Dockerfile
│ └── back
│ └── Dockerfile
├── back
└── docker-compose.yml
FROM node:20.9.0
WORKDIR /app
COPY package*.json ./
RUN npm i -g @nestjs/cli
RUN yarn install
COPY . .
CMD ["npm", "run", "start"]
FROM node:20.9.0
WORKDIR /app
COPY package*.json ./
RUN yarn install
COPY . .
CMD ["npm", "run", "dev"]
ディレクトリ、ファイルが作成できたら、dockerを立ち上げます。
docker-compose up -d
localhost:3000
と、localhost:5000
が立ち上がればOKです。
Nest.jsで作成したAPIをNext.jsで取得してみる
Nest.jsでAPIを作成
/back
ディレクトリに移動して、 module
、posts
、service
を作成します。
cd back
nest generate module posts
nest generate controller posts
nest generate service posts
/src/posts
にファイルが生成されるので、それぞれ記述していきます。
import { Injectable } from '@nestjs/common';
@Injectable()
export class PostsService {
private readonly posts = [
{
id: 1,
title: 'title 1',
content: 'content 1',
},
{
id: 2,
title: 'title 2',
content: 'content 2',
},
];
findAll() {
return this.posts;
}
}
import { Controller, Get } from '@nestjs/common';
import { PostsService } from './posts.service';
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
@Get()
findAll() {
return this.postsService.findAll();
}
}
一度docker環境を落としてから、再度立ち上げ、localhost:5000
にアクセスすると、json APIが表示されます。
Next.jsでAPIを取得
Next.jsで生成されたAPIの取得を試みます。
export default async function Home() {
const res = await fetch('http://localhost:5000/posts');
const data = await res.json();
return (
// ...
)
}
が、エラーが発生します。
Error: fetch failed
dockerのコンテナのIPを固定して修正します。
一度docker-compose down
してから、docker-compose.yml
を編集します。
version: "3.8"
services:
api:
build:
context: ./docker/back
dockerfile: Dockerfile
volumes:
- ./back:/app
ports:
- "5000:5000"
networks:
- - app-network
+ fixed_compose_network:
+ ipv4_address: 192.168.188.2
front:
build:
context: ./docker/front
dockerfile: Dockerfile
volumes:
- ./front:/app
ports:
- "3000:3000"
networks:
- - app-network
+ fixed_compose_network:
+ ipv4_address: 192.168.188.3
networks:
- app-network:
- driver: bridge
+ fixed_compose_network:
+ ipam:
+ driver: default
+ config:
+ - subnet: 192.168.188.0/24
urlを指定していたファイルのlocalhost
の部分を指定したIPに変更します。
export default async function Home() {
- const res = await fetch('http://localhost:5000/posts');
+ const res = await fetch('http://192.168.188.2:5000/posts');
const data = await res.json();
return (
// ...
)
}
これでエラーなく、データを取得できます。
Discussion