[Nestjs] Setting Up a NestJS Monorepo with Docker
Introduction
In this post, I will introduce how to set up a monorepo in NestJS and configure it with Docker for real-time development.
Let’s begin!
What is Monorepo?
A Monorepo (short for “monolithic repository”) is a single version-controlled repository that holds the code for multiple projects, which may or may not be related to one another. Instead of having separate repositories for each project, a monorepo combines them into one.
Step: 1. Install the NestJS CLI.
1
npm install -g @nestjs/cli
Step: 2. Create a new Monorepo project.
1
2
nest new nestjs-monorepo-docker
cd nestjs-monorepo-docker
Step: 3. Set Up the Monorepo
I will create the admin
and user
apps, along with the entity
and common
libraries for shared use.
apps/admin
: Admin appapps/user
: User applibs/common
: For shared utilities, interceptors, filters, etc.libs/entity
: For shared entity definitions (e.g., when using TypeORM)
- Use the NestJS CLI to add the admin, user, common, and entity modules.
1 2 3 4
nest generate app admin nest generate app user nest generate lib common nest generate lib entity
- Final Folder Structure Example:
1 2 3 4 5 6 7 8 9 10
nestjs-monorepo-docker ├── apps │ ├── admin │ └── user ├── libs │ ├── common │ └── entity ├── docker-compose.yml ├── package.json └── tsconfig.json
Step: 4. Remove Unnecessary Folders and Modify nest-cli.json
At this step, there will be a total of three folders inside the apps directory: admin, user, and nestjs-monorepo-docker. You can delete the nestjs-monorepo-docker folder.
- Modify
nest-cli.json
In this file, change the sourceRoot to src
and remove any settings related to nestjs-monorepo-docker under projects.
- Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"monorepo": true,
"projects": {
"admin": {
"type": "application",
"root": "apps/admin",
"entryFile": "main",
"sourceRoot": "apps/admin/src",
"compilerOptions": {
"tsConfigPath": "apps/admin/tsconfig.app.json"
}
},
"user": {
"type": "application",
"root": "apps/user",
"entryFile": "main",
"sourceRoot": "apps/user/src",
"compilerOptions": {
"tsConfigPath": "apps/user/tsconfig.app.json"
}
},
"common": {
"type": "library",
"root": "libs/common",
"entryFile": "index",
"sourceRoot": "libs/common/src",
"compilerOptions": {
"tsConfigPath": "libs/common/tsconfig.lib.json"
}
},
"entity": {
"type": "library",
"root": "libs/entity",
"entryFile": "index",
"sourceRoot": "libs/entity/src",
"compilerOptions": {
"tsConfigPath": "libs/entity/tsconfig.lib.json"
}
}
}
}
Step: 5. Write the Dockerfile and modify the package.json.
apps/admin/Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN yarn install
COPY . .
RUN yarn build:admin
CMD ["yarn", "start:admin"]
The user Dockerfile can be set up similarly, but replace admin with user.
- Add the following scripts to
package.json
:
1
2
3
4
5
6
"scripts":{
"start:user": "nest start user --watch",
"start:admin": "nest start admin --watch",
"build:user": "nest build user",
"build:admin": "nest build admin",
}
Step: 6. Write the docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
services:
admin:
build:
context: .
dockerfile: apps/admin/Dockerfile
ports:
- '3001:3000'
volumes:
- .:/app
- /app/node_modules
command: yarn start:admin
depends_on:
- db
user:
build:
context: .
dockerfile: apps/user/Dockerfile
ports:
- '3000:3000'
volumes:
- .:/app
- /app/node_modules
command: yarn start:user
depends_on:
- db
db:
image: postgres:15
ports:
- '5432:5432'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Step: 7. Run Docker Compose
1
docker-compose up --build
- Check the Connect PostgreSQL
postgresql
: http://localhost:5432
- Check the NestJS App
user
: http://localhost:3000admin
: http://localhost:3001
Conclusion
Today, I worked on setting up a NestJS project as a monorepo, deploying it to Docker, and configuring it for real-time code builds.
A monorepo structure makes development more convenient by enabling the use of shared modules and a common database, which improves reusability and simplifies code management.
I hope you can use this sample app as a foundation to create your own amazing projects!
Thank you for reading, and happy blogging! 🚀