A production-ready, multi-tenant SaaS backend built using Node.js, TypeScript, Docker, PostgreSQL, and Redis.
This repository is intended as a real-world reference implementation demonstrating backend architecture, system design, and cloud-ready development practices suitable for SaaS products.
Note for readers:
For most use cases, the sections Overview, Architecture, and Local Development Setup are sufficient to get started.
Deployment and advanced sections are provided for completeness and real-world scenarios.
This backend is designed with a modular, feature-based architecture that supports:
- Multi-tenancy
- Authentication & authorization
- Clean separation of concerns
- Cloud-ready deployment
It is ideal as a foundation for SaaS products, MVPs, and startup backends.
- Node.js + TypeScript REST API
- Modular, feature-based architecture
- Multi-tenant support with tenant isolation
- JWT-based authentication
- Role-based access control (RBAC)
- PostgreSQL for persistent data
- Redis for caching and performance
- Dockerized for local and production use
- CI-ready structure (GitHub Actions compatible)
| Layer | Technology |
|---|---|
| Language | TypeScript |
| Runtime | Node.js |
| Framework | Express |
| Database | PostgreSQL |
| Cache | Redis |
| ORM | TypeORM |
| Authentication | JWT |
| Containers | Docker |
| CI/CD | GitHub Actions |
| Cloud Ready | AWS-compatible |
- Modular monolith (microservice-ready)
- Feature-based modules (auth, users, tenants, subscriptions)
- Controllers handle HTTP concerns
- Services contain business logic
- Centralized middleware for auth, tenant resolution, and errors
This structure allows easy migration to microservices if required.
- Each request is associated with a
tenantId - Tenant context is resolved via middleware
- All database queries are scoped to the tenant
- Prevents cross-tenant data access
This approach ensures data isolation and scalability for SaaS environments.
saas-backend-node/
├── .github/
│ └── workflows/
│ └── ci.yml
│
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yml
│
├── src/
│ ├── app.ts
│ ├── server.ts
│ │
│ ├── docs/
│ │ ├── swagger-options.ts
│ │ └── swagger.ts
│ │
│ ├── config/
│ │ ├── env.ts
│ │ ├── data-source.ts # TypeORM DataSource
│ │ ├── redis.ts
│ │ └── logger.ts
│ │
│ ├── database/
│ │ ├── entities/
│ │ │ ├── base.entity.ts
│ │ │ ├── user.entity.ts
│ │ │ ├── tenant.entity.ts
│ │ │ └── subscription.entity.ts
│ │ │
│ │ └── migrations/
│ │
│ ├── modules/
│ │ ├── auth/
│ │ │ ├── auth.controller.ts
│ │ │ ├── auth.service.ts
│ │ │ ├── auth.routes.ts
│ │ │ └── auth.types.ts
│ │ │
│ │ ├── users/
│ │ │ ├── user.controller.ts
│ │ │ ├── user.service.ts
│ │ │ ├── user.routes.ts
│ │ │ └── user.types.ts
│ │ │
│ │ ├── tenants/
│ │ │ ├── tenant.controller.ts
│ │ │ ├── tenant.service.ts
│ │ │ ├── tenant.routes.ts
│ │ │ └── tenant.types.ts
│ │ │
│ │ └── subscriptions/
│ │ ├── subscription.controller.ts
│ │ ├── subscription.service.ts
│ │ ├── subscription.routes.ts
│ │ └── subscription.types.ts
│ │
│ ├── common/
│ │ ├── middleware/
│ │ │ ├── auth.middleware.ts
│ │ │ ├── tenant.middleware.ts
│ │ │ └── error.middleware.ts
│ │ │
│ │ ├── utils/
│ │ │ ├── jwt.ts
│ │ │ ├── password.ts
│ │ │ ├── pagination.ts
│ │ │ └── response.ts
│ │ │
│ │ └── constants/
│ │ └── roles.ts
│ │
│ ├── routes.ts
│ └── health.ts
│
├── tests/
│ ├── auth.test.ts
│ ├── user.test.ts
│ └── tenant.test.ts
│
├── .env.example
├── package.json
├── tsconfig.json
└── README.mdBefore you begin, ensure you have the following installed:
- Node.js (v18 or higher) - Download
- npm or yarn - Package manager
- Docker and Docker Compose - Download
- PostgreSQL (v14 or higher) - For local development without Docker
- Redis (v6 or higher) - For caching
- Git - Version control
git clone https://github.com/abinpanil/saas-backend-node.git
cd saas-backend-nodenpm installCreate a .env file in the root directory:
cp .env.example .envUpdate the .env file with your configuration:
# Start PostgreSQL and Redis containers
docker-compose up -d postgres redis
# Run migrations
npm run migration:run# Create database
createdb saas_backend
# Run migrations
npm run migration:run# Development mode with hot reload
npm run dev
# Production build
npm run build
npm startThe server will start at http://localhost:3000
This project uses Swagger/OpenAPI for interactive API documentation.
Once the server is running, visit:
http://localhost:3000/api-docs
- Interactive API Explorer - Test endpoints directly from the browser
- Request/Response Schemas - View detailed data models
- Authentication Testing - Test protected endpoints with JWT tokens
- Auto-generated - Documentation updates automatically from code annotations
This project includes separate Docker configurations for development and production environments.
For local development with hot reload:
# Start all services (app, postgres, redis) in development mode
cd docker
docker-compose -f docker-compose.dev.yml up --build
# Or run in detached mode
docker-compose -f docker-compose.dev.yml up -d
# View logs
docker-compose -f docker-compose.dev.yml logs -f app-dev
# Stop services
docker-compose -f docker-compose.dev.yml down
# Stop and remove volumes (clean slate)
docker-compose -f docker-compose.dev.yml down -v
**Features:**
- Hot reload with volume mounting
- Development dependencies included
# Navigate to docker directory
cd docker
# Build and start all services
docker-compose up --build -d
# View logs
docker-compose logs -f app
# Stop services
docker-compose down3. Production Features
- Multi-stage build for optimized image size
- Non-root user for security
- Production dependencies only
- Health checks for all services
- Persistent volumes for data
- Automatic restart policies
# View running containers
docker-compose ps
# View logs for specific service
docker-compose logs -f postgres
docker-compose logs -f redis
docker-compose logs -f app
# Execute commands in container
docker-compose exec app sh
docker-compose exec postgres psql -U postgres -d saas_backend
# Rebuild specific service
docker-compose build app
# Remove all containers and volumes
docker-compose down -v
# View resource usage
docker statsThe project uses different environment files for different contexts:
.env.example- Template with all available variables.env.development- Development configuration (used by docker-compose.dev.yml)docker/.env.production- Production configuration (used by docker-compose.yml)
- Push Docker Image to ECR
# Authenticate Docker to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
# Tag and push image
docker tag saas-backend-node:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/saas-backend-node:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/saas-backend-node:latest- Set Up RDS (PostgreSQL) and ElastiCache (Redis)
- Create RDS PostgreSQL instance
- Create ElastiCache Redis cluster
- Update security groups to allow ECS access
- Create ECS Task Definition
- Define container with environment variables
- Set up CloudWatch logging
- Configure health checks
- Deploy to ECS
- Create ECS cluster
- Create service with load balancer
- Configure auto-scaling
# Initialize EB
eb init -p docker saas-backend-node
# Create environment
eb create production
# Deploy
eb deploy# Login to Heroku
heroku login
# Create app
heroku create your-app-name
# Add PostgreSQL and Redis
heroku addons:create heroku-postgresql:hobby-dev
heroku addons:create heroku-redis:hobby-dev
# Set environment variables
heroku config:set NODE_ENV=production
heroku config:set JWT_SECRET=your_secret_key
# Deploy
git push heroku main
# Run migrations
heroku run npm run migration:run- Connect your GitHub repository
- Configure build and run commands:
- Build Command:
npm install && npm run build - Run Command:
npm start
- Build Command:
- Add environment variables in the dashboard
- Add PostgreSQL and Redis databases
- Deploy
npm run migration:generate -- -n MigrationNamenpm run migration:runnpm run migration:revert# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage- GraphQL API support
- WebSocket real-time features
- Advanced caching strategies
- Monitoring and observability (Prometheus, Grafana)
- Rate limiting per tenant
- API versioning
- Automated backup strategies