Quick Start
This guide walks you through setting up a complete local development environment for the Enterprise Backend Blueprint β a multi-service NestJS monorepo with PostgreSQL, Redis, and MinIO.
Prerequisites
Section titled βPrerequisitesβRequired Software
Section titled βRequired Softwareβ| Software | Version | Notes |
|---|---|---|
| Node.js | 22 LTS+ | Use NVM for version management |
| npm | 10.x+ | Bundled with Node.js |
| PostgreSQL | 17.x+ | Primary relational database |
| Redis | 7.x+ | Sessions, stateful JWT, and BullMQ job queues |
| MinIO | Latest | S3-compatible object storage for file handling |
π‘ Tip: For local infrastructure (PostgreSQL, Redis, MinIO), the fastest path is Docker Compose. See the
docker-compose.ymlin the repository root to spin everything up in one command.
Recommended VS Code Extensions
Section titled βRecommended VS Code Extensionsβ- ESLint β real-time linting feedback
- Prettier - Code Formatter β auto-formatting on save
- Todo Tree β surface
TODOandFIXMEcomments across the codebase - Markdown Preview Mermaid Support β render architecture diagrams inline
Installation
Section titled βInstallationβ1. Clone the Repository
Section titled β1. Clone the Repositoryβgit clone <repository-url>cd enterprise-backendThis project uses Git submodules for shared libraries. After cloning, initialize them:
git submodule sync --recursive && git submodule update --init --recursiveπ SSH Key Setup: If your submodules are hosted on a separate Git server and require a dedicated SSH key, generate one with
ssh-keygen -t ed25519 -C "you@example.com"and add the resulting public key to your Git provider. Then configure~/.ssh/configwith aHostalias pointing to the correctIdentityFile, and update.gitmodulesto use that alias instead of the raw hostname.
2. Install Dependencies
Section titled β2. Install Dependenciesβnpm install3. Configure Environment Variables
Section titled β3. Configure Environment Variablesβcp .env.example .envEdit .env with your local values:
# ββ Database βββββββββββββββββββββββββββββββββββββββββββββDB_MASTER_HOST=localhostDB_MASTER_PORT=5432DB_MASTER_USERNAME=your_db_userDB_MASTER_PASSWORD=your_db_password
# ββ Redis (Sessions & Stateful JWT) ββββββββββββββββββββββREDIS_HOST=localhostREDIS_PORT=6379
# ββ Redis (BullMQ Job Queue) βββββββββββββββββββββββββββββREDIS_BULLMQ_HOST=localhostREDIS_BULLMQ_PORT=6379# REDIS_BULLMQ_PASSWORD=your_password # Uncomment if auth is enabled
# ββ MinIO (Object Storage) βββββββββββββββββββββββββββββββMINIO_ENDPOINT=localhostMINIO_PORT=9000MINIO_ACCESS_KEY=minioadminMINIO_SECRET_KEY=minioadmin
# ββ Auth βββββββββββββββββββββββββββββββββββββββββββββββββJWT_SECRET=change-me-in-productionDatabase Setup
Section titled βDatabase Setupβ1. Create the Required Databases
Section titled β1. Create the Required DatabasesβConnect to PostgreSQL and create three databases β one per bounded domain:
CREATE DATABASE app_core_db;CREATE DATABASE app_master_db;CREATE DATABASE app_iam_db;Why three databases? Each bounded context owns its data. Separating them at the database level enforces domain boundaries and allows independent scaling and backup strategies.
2. Run Migrations
Section titled β2. Run Migrationsβnpm run migration:run:allStarting the Services
Section titled βStarting the ServicesβOption A: Start Everything (Recommended)
Section titled βOption A: Start Everything (Recommended)βnpm run start:dev:allThis starts all microservices concurrently with hot-reload enabled via Nx. Ideal for active feature development where you need the full system running.
Option B: Start Individual Services
Section titled βOption B: Start Individual ServicesβFor targeted development, you can start just the services you need:
# Auth Service (handles login, token issuance, session management)npm run start:dev:auth # HTTP :5001 | Microservice TCP :5000
# IAM Service (roles, permissions, access control)npm run start:dev:iam # HTTP :5003 | Microservice TCP :5002
# Core Bounded Context A (primary domain logic)npm run start:dev:service-a # HTTP :3000 | Microservice TCP :4000
# Core Bounded Context B (secondary domain logic)npm run start:dev:service-b # HTTP :3001 | Microservice TCP :4001
# Master Data Service (reference/lookup data)npm run start:dev:master # HTTP :6001 | Microservice TCP :6000
# Storage Service (file upload/download via MinIO)npm run start:dev:storage # HTTP :3002 | Microservice TCP :4002
# System Admin (back-office operations)npm run start:dev:system-admin # HTTP :3088 | Microservice TCP :4088
# Aggregated API Documentation Gatewaynpm run start:dev:docs # HTTP :9999Service Architecture
Section titled βService ArchitectureβThe system is structured as a dual-port microservice pattern: each bounded context exposes both an HTTP interface (for external clients) and a TCP interface (for internal microservice-to-microservice communication).
graph TB
Client[Client / Frontend]
subgraph "HTTP Layer (External)"
Auth[Auth Service :5001]
IAM[IAM Service :5003]
SvcA[Service A :3000]
SvcB[Service B :3001]
Master[Master Data :6001]
Storage[Storage :3002]
SysAdmin[System Admin :3088]
Docs[API Docs Gateway :9999]
end
subgraph "Microservice Layer (Internal TCP)"
AuthMS[Auth MS :5000]
IAMMS[IAM MS :5002]
SvcAMS[Service A MS :4000]
SvcBMS[Service B MS :4001]
MasterMS[Master MS :6000]
StorageMS[Storage MS :4002]
SysAdminMS[SysAdmin MS :4088]
end
subgraph "Infrastructure"
DB[(PostgreSQL\nPrimary + Replica)]
Redis[(Redis\nSessions + Queue)]
Minio[(MinIO\nObject Storage)]
end
Client --> Auth
Client --> SvcA
Client --> SvcB
Client --> Docs
Auth --> AuthMS
SvcA --> SvcAMS
SvcB --> SvcBMS
SvcBMS --> SvcAMS
AuthMS --> Redis
SvcAMS --> DB
StorageMS --> Minio
Why dual-port? HTTP controllers handle validation, auth guards, and response shaping for external consumers. The TCP microservice layer handles internal RPC calls between services with lower overhead and without re-running auth middleware. This separation keeps internal and external contracts explicit and independently evolvable.
Verifying the Setup
Section titled βVerifying the Setupβ1. Confirm Services are Running
Section titled β1. Confirm Services are RunningβEach service logs its bound address on startup:
[Auth] Listening on http://localhost:5001[IAM] Listening on http://localhost:5003[Service-A] Listening on http://localhost:3000...2. Browse the API Documentation
Section titled β2. Browse the API DocumentationβThe aggregated Swagger documentation for all services is available at:
http://localhost:9999Individual service docs are also available at their own /api-docs route:
http://localhost:5001/auth/v1/api-docs β Authhttp://localhost:3000/v1/api-docs β Service Ahttp://localhost:3001/v1/api-docs β Service B3. Quick Health Check
Section titled β3. Quick Health Checkβ# Test that the auth service is alivecurl http://localhost:5001/auth/v1/health
# Test a login endpointcurl -X POST http://localhost:5001/auth/v1/login \ -H "Content-Type: application/json" \ -d '{"username": "admin", "password": "password"}'Troubleshooting
Section titled βTroubleshootingβPort Already in Use
Section titled βPort Already in UseβError: EADDRINUSE: address already in use :::3000Find and kill the conflicting process:
lsof -i :3000 # find the PIDkill -9 <PID>PostgreSQL Connection Refused
Section titled βPostgreSQL Connection Refusedβ- Check that PostgreSQL is running:
pg_isready - Verify credentials in your
.envfile - Confirm the databases were created:
\linsidepsql
Redis Connection Refused
Section titled βRedis Connection RefusedβError: connect ECONNREFUSED 127.0.0.1:6379Start Redis:
# macOS (Homebrew)brew services start redis
# Linux (systemd)sudo systemctl start redis
# Directredis-serverMinIO Unavailable
Section titled βMinIO Unavailableβminio server /path/to/data --console-address ":9001"MinIOβs web console will be at http://localhost:9001 (default credentials: minioadmin / minioadmin).
Common Development Commands
Section titled βCommon Development Commandsβ# ββ Testing βββββββββββββββββββββββββββββββββββββββββββββββnpm test # Run all unit testsnpm run test:watch # Watch modenpm run test:cov # With coverage report
# ββ Linting βββββββββββββββββββββββββββββββββββββββββββββββnpm run lint # Lint all filesnpm run lint:fix # Auto-fix lint issues
# ββ Build βββββββββββββββββββββββββββββββββββββββββββββββββnpm run build:all # Build all servicesnpm run build:auth # Build a single service
# ββ Database Migrations βββββββββββββββββββββββββββββββββββnpm run migration:generate:core -- --name=CreateUsersTablenpm run migration:generate:master -- --name=AddLookupIndexnpm run migration:generate:iam -- --name=AddRolePermissionsnpm run migration:run:all # Apply all pending migrationsNext Steps
Section titled βNext StepsβWith your environment running, explore these guides:
- Project Structure β understand the Nx monorepo layout
- Clean Architecture β the layering philosophy behind every module
- API Response & Error Handling β standardized response contracts
- Security: Stateful JWT + Redis β how authentication works end-to-end
- Database Overview β primary/replica topology and bounded context data ownership