This is a monorepo project that contains a Nest.js API and a Vite React client. The project uses Lerna
to manage the monorepo and Docker Compose
to run the services.
Before you begin, ensure you have following installed on your machine:
👉 Node.js (LTS version)
👉 NPM
👉 Docker Desktop (including Docker Compose)
💥💥💥 DO NOT "npm install" from host! Always install packages from inside a running docker container!!! 💥💥💥
To get started, clone the repository and run the following commands:
# Create .env file in packages/api
cd packages/api
cp .env.example .env
# Create .env file in packages/client
cd packages/client
cp .env.example .env
To run the project, use the following command:
# Start Development
docker compose --profile development up -d
# Stop Development
docker compose --profile development down
# Start / Stop / Restart All Services
docker compose --profile development <start|stop|restart>
# Start / Stop / Restart Specific Service
docker compose --profile development <start|stop|restart> <service-name>
# Production
docker compose --profile production up -d
# Stop Production
docker compose --profile production down
💥💥💥 DO NOT "npm install <package-name>" from host! Always install packages from inside a running docker container!!! 💥💥💥
To install packages, use the following flow:
👉 Open Docker Desktop
👉 Open the container in which you want to install packages
👉 Open the Exec Console
👉 Run the following command:
npm install <package-name>
💥 It is important to install packages from inside the container to ensure that the correct dependencies are installed which can work cross-platform.
Following the above steps will install the packages in the node_modules
directory of the container which is mounted to the node_modules
directory of the host machine (your computer) ensuring the IDE intellisense works correctly.
You can check the Ports for every service in the docker-compose.yml
file.
👉 API: http://localhost:3000
👉 Client: http://localhost:3001
The project has the following directory structure:
├── docker-compose.yml
├── Dockerfile.dev (for development)
├── package.json
├── package-lock.json
├── README.md
├── node_modules (root node_modules)
├── packages
│ ├── api
│ | ├── ...
│ │ ├── Dockerfile (project specific Dockerfile)
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── .env.example
│ │ ├── .env (project specific environment variables)
│ │ ├── node_modules (project specific node_modules)
│ │ ├── src
│ │ │ ├── ... (Nest.js code)
│ │ │ └── main.ts
│ │ └── nest-cli.json
│ └── client
│ ├── ...
│ ├── Dockerfile (project specific Dockerfile)
│ ├── package.json
│ ├── README.md
│ ├── .env.example
│ ├── .env (project specific environmentl variables)
│ ├── node_modules (project specific node_modules)
│ ├── public
│ ├── src
│ │ ├── ... (React code)
│ │ └── main.tsx
│ └── vite.config.ts
└── lerna.json
👉 There are 2 profiles in docker-compose.yml
: development
and production
.
👉 The Dockerfile.dev
in the root directory is used for development
and it has a development
stage which is used to create setup-development
service which esnures installation of packages in the monorepo before starting any other service. These installed packages are then available in host machine as well as in the containers.
👉 The Dockerfile
in the packages/api
and packages/client
directories are used for building production
images for each service.
👉 Environment Variables in development
:
- The environment variables are loaded from
.env
files. They are available in containers because we are mounting whole monorepo into the containers duringdevelopment
. - After adding, updating, deleting an environment variable, we need to restart the specific service using
docker compose --profile development restart <service-name>
in order for changes to take effect.
👉 Environment Variables in production
:
- The environment variables for
packages/client
service are defined inpackages/client/Dockerfile
because they are needed at the build time. - The environment variables for
packages/api
service are passed asenv_file
fromdocker-compose.yml
because they are needed at the runtime.