Enterprise-Grade Node.js Backend API with Advanced Features
Node.js Backend is a comprehensive, production-ready RESTful API built with Express.js, featuring JWT authentication with Instagram-style multi-token pattern, role-based access control, real-time activity logging, advanced security middleware, and comprehensive monitoring capabilities.
Repository: https://github.com/fullstack-open-source/nodejs-backend-with-sql
- π Features
- ποΈ Architecture
- π API Documentation
- π¦ Installation & Setup
- π Complete Project Workflow
- RESTful API: Comprehensive REST API with Express.js framework
- JWT Authentication: Instagram-style multi-token authentication system (Access, Session, Refresh tokens)
- Role-Based Access Control: Flexible permission system with groups and permissions
- Activity Logging: Comprehensive audit trail with detailed metadata
- File Upload: Google Cloud Storage integration for media files
- Email & SMS: Twilio and Nodemailer integration for notifications and OTP
- Error Tracking: Sentry integration for production monitoring and error tracking
- API Documentation: Auto-generated Swagger/OpenAPI documentation
- Multilingual Support: Multi-language API responses with automatic translation
- Rate Limiting: Request throttling and rate limiting for traffic management
- Worker Pool: CPU-intensive task processing with worker threads
- Docker Ready: Production-ready containerization with multi-stage builds
- PM2 Support: Process management with cluster mode for high availability
- Express.js 4.18+: Modern web framework for building APIs
- PostgreSQL 16+: Robust relational database with advanced features
- Prisma ORM: Type-safe database access with connection pooling
- Redis: Caching and session management for improved performance
- JWT: Secure token-based authentication and authorization
- Winston: Professional logging system with file rotation
- Helmet: Security headers for protection against common vulnerabilities
- Rate Limiting: Request throttling to prevent abuse
- Compression: Response compression for optimized bandwidth usage
- CORS: Cross-origin resource sharing with whitelist validation
- Swagger: Interactive API documentation with Swagger UI
- Nginx Reverse Proxy: Production-ready reverse proxy configuration
- Multilingual: Multi-language support for API responses (English, Arabic, and more)
- Multi-Token System: Access token (1 hour), Session token (7 days), Refresh token (30 days)
- Token Blacklisting: Redis-based token invalidation for secure logout
- OTP Verification: Email, SMS, and WhatsApp OTP support
- Password Management: Set, change, and reset password functionality
- Email/Phone Verification: Two-step verification for contact changes
- Session Management: Stateless session management with unique session IDs
- Token Rotation: Automatic token rotation on refresh for enhanced security
This project uses Prisma ORM, which provides exceptional database flexibility and support for multiple database systems. While the project is configured for PostgreSQL by default, Prisma allows you to easily switch between different databases without changing your application code.
- PostgreSQL 16+: The default database for this project, providing robust relational database features, JSON support, and advanced querying capabilities.
Prisma ORM supports 10+ database systems, giving you the flexibility to choose the best database for your needs:
Self-hosted Databases:
- β PostgreSQL (9.6 - 17) - Currently configured
- β MySQL (5.6, 5.7, 8.0, 8.4)
- β MariaDB (10.0+)
- β SQLite (All versions)
- β Microsoft SQL Server (2017, 2019, 2022)
- β MongoDB (4.2+)
- β CockroachDB (21.2.4+)
Managed/Cloud Databases:
- β AWS Aurora (All versions)
- β AWS Aurora Serverless (All versions)
- β Azure SQL (All versions)
- β CockroachDB-as-a-Service (All versions)
- β MongoDB Atlas (All versions)
- β Neon Serverless Postgres (All versions)
- β PlanetScale (All versions)
- β Cloudflare D1 (Preview)
- β Aiven (MySQL & Postgres)
- Database Agnostic: Switch between databases by simply changing the
providerinschema.prisma - Type Safety: Auto-generated TypeScript types based on your database schema
- Migration Management: Built-in migration system for schema versioning
- Connection Pooling: Automatic connection pool management for optimal performance
- Query Optimization: Intelligent query builder that generates optimized SQL
- Developer Experience: Intuitive API with excellent IDE autocomplete support
- Multi-Database Support: Use different databases for different environments (e.g., SQLite for development, PostgreSQL for production)
To switch to a different database, simply update the datasource provider in api/prisma/schema.prisma:
// For PostgreSQL (current)
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// For MySQL
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
// For SQLite
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
// For MongoDB
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}Then run:
# ------------------------------
# Prisma Client & Schema
# ------------------------------
# Regenerate Prisma Client after schema changes
npm run prisma:generate
# Pull the current database schema into Prisma (update schema.prisma)
npm run prisma:pull
# Push the Prisma schema to the database (without migration)
npm run prisma:push
# Open Prisma Studio (GUI to view/edit database)
npm run prisma:studio
# Format Prisma schema file
npm run prisma:format
# Validate Prisma schema for errors
npm run prisma:validate
# ------------------------------
# Database seeding & syncing
# ------------------------------
# Pull data (custom seed script)
npm run db:pull
# Push data (custom seed script)
npm run db:push
# Sync data (custom seed script)
npm run db:sync
# Seed the database with initial data
npm run db:seed
# ------------------------------
# Migrations
# ------------------------------
# Create and apply migrations (development)
npm run migrate:dev
# Apply migrations in production
npm run migrate:deploy
# Drop database and reapply all migrations (destructive)
npm run migrate:reset
Note: Some schema features may vary between databases. Refer to Prisma Database Documentation for database-specific considerations.
The system follows a layered architecture with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Proxy β
β (api.example.com) β
β SSL/TLS Termination β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Internal Nginx Proxy β
β (Port 9080:80) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Security Layer: β β
β β - Rate Limiting (200 req/min per IP) β β
β β - Request Size Validation (15MB max) β β
β β - Attack Pattern Detection β β
β β - Content Security Policy β β
β β - DDoS Protection β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Express.js Application β
β (Port 3000) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Middleware Stack: β β
β β 1. Sentry Request Handler β β
β β 2. Helmet (Security Headers) β β
β β 3. CORS (Cross-Origin) β β
β β 4. Body Parser (JSON/URL-encoded) β β
β β 5. Compression β β
β β 6. Morgan (Request Logging) β β
β β 7. Request Logger (Custom) β β
β β 8. Rate Limiter β β
β β 9. Security Middleware (Custom) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Application Modules: β β
β β - Authentication (JWT, OTP, Login) β β
β β - Profile Management β β
β β - Permissions (Groups, Permissions) β β
β β - Dashboard (Analytics) β β
β β - Activity Logging β β
β β - File Upload (GCS) β β
β β - Health Monitoring β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ-βββββ
β
ββββββββββββββ΄ββββββββββββββ
βΌ βΌ
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β PostgreSQL Database β β Redis Cache β
β (Prisma ORM) β β (Sessions, Cache) β
β - User Data β β - Session Storage β
β - Permissions β β - OTP Cache β
β - Activity Logs β β - Token Blacklist β
β - Groups β β - Rate Limiting β
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β Google Cloud Storage β
β (Media & Static Files) β
β - User Uploads β
β - Generated Content β
β - Static Assets β
ββββββββββββββββββββββββββββ
The authentication system implements a stateless, multi-token architecture similar to Instagram:
Key Features:
- Multi-Token System: Access token (1 hour), Session token (7 days), Refresh token (30 days)
- Token Blacklisting: Redis-based cache for token invalidation
- Session Management: Unique session_id links all tokens together
- Token Rotation: Refresh tokens rotate on each refresh for security
- Origin Validation: Domain-specific token validation
Complete Documentation: See Authentication Router
1. Client Request
β
βββΊ External Proxy (api.example.com)
β
βββΊ Internal Nginx (Port 9080)
β βββΊ Security Checks (Rate Limiting, Attack Detection)
β βββΊ Request Size Validation
β βββΊ Content Security Policy Headers
β βββΊ Proxy to Express (http://api:3000)
β
βββΊ Express Middleware Stack
β βββΊ Sentry Request Handler
β β βββΊ Request Context Capture
β β
β βββΊ Helmet
β β βββΊ Security Headers
β β
β βββΊ CORS
β β βββΊ Origin Validation
β β
β βββΊ Body Parser
β β βββΊ JSON Parsing (15MB limit)
β β βββΊ URL-encoded Parsing
β β
β βββΊ Compression
β β βββΊ Response Compression
β β
β βββΊ Morgan + Request Logger
β β βββΊ Request Logging
β β
β βββΊ Rate Limiter
β β βββΊ Request Throttling (200/min)
β β
β βββΊ Security Middleware
β βββΊ Input Sanitization
β βββΊ SQL Injection Detection
β βββΊ XSS Detection
β βββΊ Command Injection Detection
β
βββΊ Route Handler
β βββΊ JWT Authentication (if required)
β βββΊ Permission Check (if required)
β βββΊ Request Validation
β βββΊ Business Logic
β βββΊ Database Operations (Prisma)
β βββΊ Response Formatting
β
βββΊ Activity Logging
β βββΊ Log to Database
β
βββΊ Response
βββΊ Error Handling (if any)
βββΊ Sentry Error Capture (if error)
βββΊ Security Headers
βββΊ Client Response
The middleware stack processes requests in a specific order to ensure security, performance, and reliability:
- Sentry Request Handler - Captures request context for error tracking and performance monitoring
- Helmet - Sets security headers including X-Content-Type-Options, X-Frame-Options, and X-XSS-Protection
- CORS - Handles cross-origin requests with whitelist validation for allowed origins
- Body Parser - Parses JSON and URL-encoded request bodies with 15MB size limit
- Compression - Compresses responses using gzip algorithm for bandwidth optimization
- Morgan + Request Logger - Logs HTTP requests with detailed metadata including IP, method, path, and response time
- Rate Limiter - Throttles requests to 200 requests per minute per IP address
- Security Middleware - Sanitizes input data and detects attack patterns including SQL injection, XSS, and command injection
- Route Handlers - Application-specific logic execution
- Error Handler - Catches and formats errors with appropriate status codes
- Sentry Error Handler - Captures errors for monitoring and alerting
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PostgreSQL Database β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β User Model β β
β β - user_id (UUID, Primary Key) β β
β β - email, phone_number, user_name β β
β β - password, auth_type β β
β β - is_email_verified, is_phone_verified β β
β β - status, is_active, is_verified β β
β β - profile_picture_url, bio β β
β β - Relationships: UserGroup[], ActivityLog[] β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Permission Model β β
β β - permission_id (UUID, Primary Key) β β
β β - name, codename (unique) β β
β β - description, category β β
β β - Relationships: GroupPermission[] β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Group Model β β
β β - group_id (UUID, Primary Key) β β
β β - name, codename (unique) β β
β β - description, is_system, is_active β β
β β - Relationships: GroupPermission[], UserGroup[] β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β GroupPermission Model (Many-to-Many) β β
β β - id (UUID, Primary Key) β β
β β - group_id (FK β Group) β β
β β - permission_id (FK β Permission) β β
β β - Unique constraint: (group_id, permission_id) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β UserGroup Model (Many-to-Many) β β
β β - id (UUID, Primary Key) β β
β β - user_id (FK β User) β β
β β - group_id (FK β Group) β β
β β - assigned_at, assigned_by_user_id β β
β β - Unique constraint: (user_id, group_id) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β ActivityLog Model β β
β β - log_id (UUID, Primary Key) β β
β β - user_id (FK β User, nullable) β β
β β - level, message, action, module β β
β β - ip_address, user_agent, device, browser, os β β
β β - endpoint, method, status_code β β
β β - request_id, session_id β β
β β - metadata, error_details (JSONB) β β
β β - duration_ms, created_at β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NodeJs Backend API
βββ π api/ # Main application directory
β βββ π server.js # Express server entry point
β βββ π Dockerfile # Multi-stage Docker build
β βββ π ecosystem.config.js # PM2 configuration
β βββ π package.json # Dependencies and scripts
β βββ π start.sh # Container startup script
β β
β βββ π router/ # API route handlers
β β βββ π authenticate/ # Authentication routes
β β β βββ authenticate.js # Login, OTP, token management
β β β βββ profile.js # User profile management
β β β βββ models.js # Request validation schemas
β β β βββ query.js # Database queries
β β β βββ utils.js # Helper functions
β β β
β β βββ π dashboard/ # Dashboard routes
β β β βββ api.js # Analytics and statistics
β β β
β β βββ π permissions/ # Permission management
β β β βββ api.js # Groups, permissions, users
β β β
β β βββ π activity/ # Activity logging
β β β βββ api.js # Activity log endpoints
β β β
β β βββ π€ upload/ # File upload
β β β βββ api.js # Media upload endpoints
β β β
β β βββ β€οΈ health/ # Health monitoring
β β βββ api.js # Health check endpoints
β β βββ test-sentry.js # Sentry test endpoint
β β
β βββ π src/ # Source code modules
β β βββ π authenticate/ # Authentication logic
β β β βββ authenticate.js # JWT validation
β β β βββ checkpoint.js # User authentication
β β β βββ models.js # User models
β β β βββ otp_cache.js # OTP management
β β β
β β βββ π activity/ # Activity logging
β β β βββ activityLog.js # Activity log service
β β β
β β βββ πΎ cache/ # Caching layer
β β β βββ cache.js # Redis cache utilities
β β β
β β βββ βοΈ config/ # Configuration
β β β βββ swagger.js # Swagger/OpenAPI config
β β β
β β βββ ποΈ db/ # Database layer
β β β βββ prisma.js # Prisma client setup
β β β βββ index.js # Database utilities
β β β βββ postgres/ # PostgreSQL utilities
β β β βββ postgres.js # Connection pool
β β β βββ initTriggers.js # Database triggers
β β β
β β βββ π§ email/ # Email service
β β β βββ email.js # Email sending
β β β βββ template.js # Email templates
β β β
β β βββ π enum/ # Enumerations
β β β βββ enum.js # Application enums
β β β
β β βββ π logger/ # Logging system
β β β βββ logger.js # Winston logger
β β β
β β βββ π‘οΈ middleware/ # Express middleware
β β β βββ errorHandler.js # Global error handler
β β β βββ permissionMiddleware.js # Permission checking
β β β βββ requestLogger.js # Request logging
β β β βββ requestQueue.js # Request queuing
β β β βββ securityMiddleware.js # Security checks
β β β
β β βββ π permissions/ # Permission system
β β β βββ permissions.js # Permission utilities
β β β
β β βββ π€ response/ # Response handlers
β β β βββ success.js # Success responses
β β β βββ error.js # Error responses
β β β βββ map.js # Response mapping
β β β
β β βββ π sentry/ # Error tracking
β β β βββ sentry.js # Sentry configuration
β β β
β β βββ π± sms/ # SMS service
β β β βββ sms.js # Twilio integration
β β β
β β βββ πΎ storage/ # File storage
β β β βββ storage.js # Google Cloud Storage
β β β
β β βββ π οΈ utils/ # Utilities
β β β βββ debug.js # Debug utilities
β β β βββ workerUtils.js # Worker pool utilities
β β β
β β βββ π multilingual/ # Multilingual support
β β β βββ multilingual.js # Language utilities
β β β
β β βββ π· workers/ # Worker threads
β β βββ workerPool.js # Worker pool manager
β β βββ cpuTaskWorker.js # CPU task worker
β β
β βββ π prisma/ # Prisma ORM
β β βββ schema.prisma # Database schema
β β βββ seed.js # Database seeding
β β βββ seed-defaults.js # Default seed data
β β
β βββ π credentials/ # Service credentials
β β βββ google-backend-master.json # GCS credentials
β β
β βββ π logs/ # Application logs
β β βββ errors-server.log # Error logs
β β βββ success-server.log # Success logs
β β
β βββ π scripts/ # Utility scripts
β βββ kill-port.sh # Port cleanup
β βββ db-sync.sh # Database sync
β
βββ π nginx/ # Nginx configuration
β βββ nginx.conf # Main nginx config
β βββ proxy.conf # Proxy settings
β βββ security.conf # Security headers
β βββ conf.d/ # Additional configs
β βββ default.conf # Default server config
β βββ security.conf # Security rules
β
βββ π docker-compose.yaml # Docker Compose config
βββ π reload.sh # Deployment script
βββ π README.md # This file
Complete Documentation: Authentication Router
Endpoints:
POST /{MODE}/auth/login-with-password- Login with email/phone and passwordPOST /{MODE}/auth/login-with-otp- Login with OTPPOST /{MODE}/auth/send-one-time-password- Send OTP via email/SMS/WhatsAppPOST /{MODE}/auth/verify-one-time-password- Verify OTPPOST /{MODE}/auth/verify- Signup/Register with OTPPOST /{MODE}/auth/set-password- Set password for authenticated userPOST /{MODE}/auth/change-password- Change user passwordPOST /{MODE}/auth/forget-password- Reset password with OTPPOST /{MODE}/auth/refresh-token- Refresh access tokensPOST /{MODE}/auth/logout- Logout and revoke tokensPOST /{MODE}/auth/token-info- Get token informationPOST /{MODE}/auth/check-user-availability- Check email/phone availabilityPOST /{MODE}/auth/verify-email-and-phone- Verify email/phone with OTP
Profile Management: Profile Router
Endpoints:
GET /{MODE}/settings/profile- Get user profileGET /{MODE}/settings/profile/{user_id}- Get profile by IDPOST /{MODE}/settings/profile-picture- Update profile picturePUT /{MODE}/settings/profile- Update user profilePOST /{MODE}/settings/change-email- Change email with OTP verificationPOST /{MODE}/settings/change-phone- Change phone with OTP verificationPOST /{MODE}/settings/profile-accessibility- Update profile accessibilityPOST /{MODE}/settings/profile-language- Update profile languagePOST /{MODE}/settings/update-theme- Update theme preferencePOST /{MODE}/settings/update-timezone- Update timezoneGET /{MODE}/settings- Get user settingsPOST /{MODE}/settings/deactivate-account- Deactivate accountPOST /{MODE}/settings/delete-account- Delete account
Complete Documentation: Permissions Router
Endpoints:
GET /{MODE}/permissions- Get all permissionsGET /{MODE}/permissions/{permission_id}- Get permission by IDPOST /{MODE}/permissions- Create new permissionPUT /{MODE}/permissions/{permission_id}- Update permissionDELETE /{MODE}/permissions/{permission_id}- Delete permissionGET /{MODE}/groups- Get all groupsGET /{MODE}/groups/{group_id}- Get group by IDPOST /{MODE}/groups- Create new groupPUT /{MODE}/groups/{group_id}- Update groupDELETE /{MODE}/groups/{group_id}- Delete groupPOST /{MODE}/groups/{group_id}/permissions- Assign permissions to groupGET /{MODE}/users/{user_id}/groups- Get user groupsGET /{MODE}/users/{user_id}/permissions- Get user permissionsPOST /{MODE}/users/{user_id}/groups- Assign groups to userGET /{MODE}/users/me/groups- Get current user groupsGET /{MODE}/users/me/permissions- Get current user permissions
Complete Documentation: Dashboard Router
Endpoints:
GET /{MODE}/dashboard/overview- Get dashboard overview statisticsGET /{MODE}/dashboard/users-by-status- Get users grouped by statusGET /{MODE}/dashboard/users-by-type- Get users grouped by typeGET /{MODE}/dashboard/users-by-auth-type- Get users grouped by auth typeGET /{MODE}/dashboard/users-by-country- Get users grouped by countryGET /{MODE}/dashboard/users-by-language- Get users grouped by languageGET /{MODE}/dashboard/user-growth- Get user growth statisticsGET /{MODE}/dashboard/role-statistics- Get role/group statisticsGET /{MODE}/dashboard/recent-sign-ins- Get recent sign-in activityGET /{MODE}/dashboard/all-statistics- Get all statistics
Complete Documentation: Upload Router
Endpoints:
POST /{MODE}/upload/media- Upload media file (direct upload or URL)DELETE /{MODE}/upload/media/{file_id}- Delete uploaded media
Features:
- Direct file upload with multipart/form-data
- URL-based upload (downloads and stores file from URL)
- Google Cloud Storage integration
- Automatic file validation and processing
- Support for images, videos, and documents
Complete Documentation: Activity Router
Endpoints:
GET /{MODE}/activity- Get activity logs with filteringGET /{MODE}/activity/{log_id}- Get specific activity logPOST /{MODE}/activity- Create activity log entry
Features:
- Comprehensive audit trail
- User action tracking
- Request/response logging
- Error logging with details
- Metadata storage (JSONB)
Complete Documentation: Health Router
Endpoints:
GET /health- Basic health check (no prefix)GET /{MODE}/health- Detailed health checkGET /{MODE}/health/system- System health with metricsGET /{MODE}/health/database- Database connection healthGET /{MODE}/health/storage- Storage (GCS) health checkGET /{MODE}/health/test-sentry- Test Sentry integration
System Requirements:
- OS: Linux (Ubuntu 20.04+), macOS, or Windows with WSL2
- Node.js: 18.0 or higher
- npm: 9.0 or higher
- PostgreSQL: 12+ (for production)
- Redis: 6+ (optional, for caching)
- Docker: 20.10+ (for containerized deployment)
- Docker Compose: 2.0+ (for multi-container orchestration)
- Google Cloud Storage: Account and bucket (for media files)
Development Tools:
- Git 2.30+
- Code editor (VS Code recommended)
- Postman or similar API testing tool
git clone https://github.com/fullstack-open-source/nodejs-backend-with-sql.git
cd nodejs-backend-with-sql# Copy example environment file
cp example.env .env
# Edit .env file with your configuration
nano .envIf you plan to use file upload features, you need to configure Google Cloud Storage credentials:
# Navigate to credentials directory
cd api/credentials
# Copy the template credential file
cp "google-backend-master copy.json" google-backend-master.json
# Edit the credential file with your Google Cloud Service Account credentials
nano google-backend-master.jsonHow to get Google Cloud Service Account credentials:
- Go to Google Cloud Console
- Select or create a project
- Navigate to IAM & Admin β Service Accounts
- Create a new service account or select an existing one
- Click on the service account β Keys tab
- Click Add Key β Create new key β Choose JSON format
- Download the JSON file
- Copy the contents of the downloaded JSON file into
api/credentials/google-backend-master.json
Important Notes:
- The template file
google-backend-master copy.jsonis provided as a reference - Your actual credentials file
google-backend-master.jsonis ignored by git (for security) - Make sure your service account has the necessary permissions for Google Cloud Storage
- Update
GOOGLE_STORAGE_BUCKET_NAMEin your.envfile with your bucket name
# Create Docker network (if not exists)
docker network create nodejs_backend_with_postgresql_network
# Start all services
docker compose up -d
# Check service status
docker compose ps
# View logs
docker compose logs -f api# Generate Prisma Client
docker compose exec api npm run prisma:generate
# Push schema to database
docker compose exec api npm run db:push
# Seed database (optional)
docker compose exec api npm run db:seed
# Apply migrations
docker compose exec api npm run migrate:dev
# Inspect DB with Prisma Studio
docker compose exec api npm run prisma:studio - API Base: http://localhost:9080
- API Docs: http://localhost:9080/api-docs
- Health Check: http://localhost:9080/health (no prefix) or http://localhost:9080/{MODE}/health
- API Routes: http://localhost:9080/{MODE}/* (e.g., /prod/v1/authenticate, /dev/v1/token)
- pgAdmin: http://localhost:5050 (if enabled)
Note: Replace {MODE} with your configured MODE value (e.g., prod/v1 or dev/v1)
All API routes are prefixed with the MODE environment variable. This allows you to version your API and separate environments.
Configuration in .env:
MODE=prod/v1 # For production API version 1
# or
MODE=dev/v1 # For development API version 1API Route Examples:
If MODE=prod/v1, all routes will be prefixed with /prod/v1/:
- Health Check:
http://localhost:9080/prod/v1/health - Authentication:
http://localhost:9080/prod/v1/authenticate - Login:
http://localhost:9080/prod/v1/token - Profile:
http://localhost:9080/prod/v1/settings - Dashboard:
http://localhost:9080/prod/v1/dashboard - Permissions:
http://localhost:9080/prod/v1/permissions - Activity:
http://localhost:9080/prod/v1/activity
If MODE=dev/v1, all routes will be prefixed with /dev/v1/:
- Health Check:
http://localhost:9080/dev/v1/health - Authentication:
http://localhost:9080/dev/v1/authenticate - Login:
http://localhost:9080/dev/v1/token - Profile:
http://localhost:9080/dev/v1/settings - Dashboard:
http://localhost:9080/dev/v1/dashboard - Permissions:
http://localhost:9080/dev/v1/permissions - Activity:
http://localhost:9080/dev/v1/activity
Note: The /health endpoint is available without the MODE prefix for health checks:
- Direct Health Check:
http://localhost:9080/health(no prefix)
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Install Docker (optional, for containerized development)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo apt install docker-compose-plugin -y# Clone repository
git clone https://github.com/fullstack-open-source/nodejs-backend-with-sql.git
cd nodejs-backend-with-sql/api
# Install dependencies
npm install# Copy example environment file
cp ../example.env ../.env
# Edit .env file with your settings
nano ../.envIf you plan to use file upload features, configure Google Cloud Storage credentials:
# Navigate to credentials directory
cd credentials
# Copy the template credential file
cp "google-backend-master copy.json" google-backend-master.json
# Edit the credential file with your Google Cloud Service Account credentials
nano google-backend-master.jsonHow to get Google Cloud Service Account credentials:
- Go to Google Cloud Console
- Select or create a project
- Navigate to IAM & Admin β Service Accounts
- Create a new service account or select an existing one
- Click on the service account β Keys tab
- Click Add Key β Create new key β Choose JSON format
- Download the JSON file
- Copy the contents of the downloaded JSON file into
api/credentials/google-backend-master.json
Important Notes:
- The template file
google-backend-master copy.jsonis provided as a reference - Your actual credentials file
google-backend-master.jsonis ignored by git (for security) - Make sure your service account has the necessary permissions for Google Cloud Storage
- Update
GOOGLE_STORAGE_BUCKET_NAMEin your.envfile with your bucket name
# Install PostgreSQL
sudo apt install postgresql postgresql-contrib -y
# Create database and user
sudo -u postgres psql << EOF
CREATE DATABASE nodejs_backend;
CREATE USER nodejs_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE nodejs_backend TO nodejs_user;
\q
EOF
# Update .env with local database connection
# DATABASE_URL=postgresql://nodejs_user:your_password@localhost:5432/nodejs_backend# ------------------------------
# Prisma Client & Schema
# ------------------------------
# Regenerate Prisma Client after schema changes
npm run prisma:generate
# Pull the current database schema into Prisma (update schema.prisma)
npm run prisma:pull
# Push the Prisma schema to the database (without migration)
npm run prisma:push
# Open Prisma Studio (GUI to view/edit database)
npm run prisma:studio
# Format Prisma schema file
npm run prisma:format
# Validate Prisma schema for errors
npm run prisma:validate
# ------------------------------
# Database seeding & syncing
# ------------------------------
# Pull data (custom seed script)
npm run db:pull
# Push data (custom seed script)
npm run db:push
# Sync data (custom seed script)
npm run db:sync
# Seed the database with initial data
npm run db:seed
# ------------------------------
# Migrations
# ------------------------------
# Create and apply migrations (development)
npm run migrate:dev
# Apply migrations in production
npm run migrate:deploy
# Drop database and reapply all migrations (destructive)
npm run migrate:reset# Seed with default data
npm run db:seed# Development mode with auto-reload
npm run dev
# Or start directly
npm start- API Base: http://localhost:3000
- API Docs: http://localhost:3000/api-docs
- Health Check: http://localhost:3000/health (no prefix) or http://localhost:3000/{MODE}/health
- API Routes: http://localhost:3000/{MODE}/* (e.g., /prod/v1/authenticate, /dev/v1/token)
- Prisma Studio: http://localhost:5555 (if running)
Note: Replace {MODE} with your configured MODE value (e.g., prod/v1 or dev/v1)
# Update system
sudo apt update && sudo apt upgrade -y
# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Install PM2
npm install -g pm2
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo apt install docker-compose-plugin -y# Clone repository
git clone https://github.com/fullstack-open-source/nodejs-backend-with-sql.git
cd nodejs-backend-with-sql
# Create production .env file
cp example.env .env
# Edit .env file with production settings
nano .envImportant: Update .env file with production values:
- Set
NODE_ENV=production - Set
API_MODE=production - Set
DEBUG_MODE=false - Configure production database credentials
- Set strong JWT secret (generate with:
openssl rand -base64 32) - Configure production Redis, Sentry, and other services
- Set
GOOGLE_STORAGE_BUCKET_NAMEwith your production bucket name
For production file uploads, configure Google Cloud Storage credentials:
# Navigate to credentials directory
cd api/credentials
# Copy the template credential file
cp "google-backend-master copy.json" google-backend-master.json
# Edit the credential file with your production Google Cloud Service Account credentials
nano google-backend-master.jsonHow to get Google Cloud Service Account credentials:
- Go to Google Cloud Console
- Select or create a project
- Navigate to IAM & Admin β Service Accounts
- Create a new service account or select an existing one
- Click on the service account β Keys tab
- Click Add Key β Create new key β Choose JSON format
- Download the JSON file
- Copy the contents of the downloaded JSON file into
api/credentials/google-backend-master.json
Production Security Notes:
- The template file
google-backend-master copy.jsonis provided as a reference - Your actual credentials file
google-backend-master.jsonis ignored by git (for security) - Use a dedicated service account with minimal required permissions
- Enable Cloud Storage API in your Google Cloud project
- Ensure your service account has Storage Object Admin or Storage Admin role
- Never commit your actual credentials file to version control
# Build and start services
docker compose build
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f api
# Run migrations
docker compose exec api npm run db:pushcd api
# Generate Prisma Client
npm run prisma:generate
# Start with PM2
npm run pm2:start
# Check status
pm2 status
# View logs
pm2 logs
# Monitor
pm2 monit# Install Nginx
sudo apt install nginx -y
# Create Nginx config
sudo nano /etc/nginx/sites-available/api.example.comAdd configuration:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:9080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}# Enable site
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx# Check Docker version
docker --version
docker compose version
# Install Docker if needed
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo apt install docker-compose-plugin -yThe docker-compose.yaml includes:
- api: Node.js application (Express server)
- db: PostgreSQL database
- redis: Redis cache and session store
- nginx: Internal reverse proxy
- pgadmin: PostgreSQL admin interface
# Create Docker network
docker network create nodejs_backend_with_postgresql_network
# Build images
docker compose build
# Start all services
docker compose up -d
# View all logs
docker compose logs -f
# View specific service logs
docker compose logs -f api
docker compose logs -f nginx# Stop services
docker compose stop
# Start services
docker compose start
# Restart services
docker compose restart
# Restart specific service
docker compose restart api
# Stop and remove containers
docker compose down
# Stop, remove containers, and volumes
docker compose down -v# Run Prisma migrations
docker compose exec api npm run db:push
# Generate Prisma Client
docker compose exec api npm run prisma:generate
# Access container shell
docker compose exec api sh
# Run database seed
docker compose exec api npm run db:seed
# Access PostgreSQL
docker compose exec db psql -U postgres -d postgres# Check service health
docker compose ps
# Test API health endpoint
curl http://localhost:8900/health
# Test Nginx health endpoint
curl http://localhost:9080/health
# Check database connection
docker compose exec api npm run prisma:studio# Create network (if not exists)
docker network create nodejs_backend_with_postgresql_network
# Verify network
docker network ls
# Inspect network
docker network inspect nodejs_backend_with_postgresql_networkβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Docker Network β
β (nodejs_backend_with_postgresql_network) β
β β
β ββββββββββββββββ β
β β Client β β
β β (Browser) β β
β ββββββββ¬ββββββββ β
β β β
β β HTTP/HTTPS (Port 9080) β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Nginx Service β β
β β Container: nodejs-backend-nginx β β
β β Port: 9080:80 (host:container) β β
β β Config: ./nginx/nginx.conf β β
β ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β Proxy to http://api:3000 β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β API Service (Node.js/Express) β β
β β Container: nodejs-backend β β
β β Port: 3000 (internal only) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Prisma Client β β β
β β β - Reads schema.prisma β β β
β β β - Generates type-safe queries β β β
β β ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β PostgreSQL Connection β
β β (postgresql://postgres:postgres@ β
β β nodejs-backend-db:5432/postgres) β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PostgreSQL Service β β
β β Container: nodejs-backend-db β β
β β Port: 5432 (internal only) β β
β β Volume: postgres_data (persistent) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Database: postgres β β β
β β β - User table β β β
β β β - Permission table β β β
β β β - Group table β β β
β β β - ActivityLog table β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β² β
β β β
β β Redis Connection β
β β (redis://nodejs-backend-redis:6379) β
β β β
β βββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββ β
β β Redis Service β β
β β Container: nodejs-backend-redis β β
β β Port: 6379 (internal only) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Cache Storage β β β
β β β - OTP cache β β β
β β β - Session storage β β β
β β β - Token blacklist β β β
β β β - Rate limiting data β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β pgAdmin Service (Optional) β β
β β Container: nodejs-backend-pgadmin β β
β β Port: 5050:80 (host:container) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Web Interface β β β
β β β - Database management β β β
β β β - Query execution β β β
β β β - Schema visualization β β β
β β ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β β PostgreSQL Connection β β
β β β (nodejs-backend-db:5432) β β
β β βΌ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Connects to PostgreSQL Service β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. Docker Network
βββΊ nodejs_backend_with_postgresql_network
2. Database Services (Start First)
βββΊ PostgreSQL (nodejs-backend-db:5432)
βββΊ Redis (nodejs-backend-redis:6379)
3. API Service (Waits for Database Health Checks)
βββΊ Connects to PostgreSQL via Prisma
βββΊ Connects to Redis for Cache
4. Nginx Service (Waits for API Health Check)
βββΊ Proxies to API (http://api:3000)
5. pgAdmin Service (Optional, Waits for Database)
βββΊ Connects to PostgreSQL
Client Request
β
βΌ
Port 9080 (Host) βββΊ Nginx βββΊ Port 3000 βββΊ API Service
β
βββΊ PostgreSQL (Port 5432)
βββΊ Redis (Port 6379)
The authentication system uses a three-token approach similar to Instagram:
-
Access Token (1 hour)
- Lightweight token for API authentication
- Minimal payload for fast validation
- Includes JTI (JWT ID) for efficient blacklisting
-
Session Token (7 days) - Recommended
- Contains full user profile and permissions
- Fastest validation (no database lookup needed)
- Preferred for frontend API calls
-
Refresh Token (30 days)
- Used to obtain new tokens when they expire
- Cannot be used for API authentication
- Rotates on each refresh for security
Complete Documentation: Authentication Router
Recommended Approach (Session Token):
// Store tokens after login
{
"access_token": "...",
"session_token": "...", // RECOMMENDED for API calls
"refresh_token": "...",
"session_id": "..."
}
// Use session_token for API calls (fastest validation)
headers = {
"X-Session-Token": session_token // Preferred
// OR
"Authorization": `Bearer ${session_token}` // Also works
}This project is open source and free to use for all purposes with no restrictions.
This project is released under the MIT License, which means:
- β Free to use for any purpose (commercial or personal)
- β No restrictions on usage, modification, or distribution
- β No warranty provided
- β Attribution is appreciated but not required
π Full License Text: See LICENSE file for complete license terms and conditions.
This project is built with amazing open-source technologies. Special thanks to:
- Node.js - JavaScript runtime built on Chrome's V8 engine
- Express.js - Fast, unopinionated web framework for Node.js
- PostgreSQL - Advanced open-source relational database
- Prisma - Next-generation ORM for Node.js and TypeScript
- Redis - In-memory data structure store
- JWT (jsonwebtoken) - JSON Web Token implementation
- bcryptjs - Password hashing library
- Helmet - Security middleware for Express
- Winston - Logging library for Node.js
- Sentry - Error tracking and performance monitoring
- Morgan - HTTP request logger middleware
- Swagger - API documentation and testing tools
- swagger-jsdoc - Swagger specification generator
- swagger-ui-express - Swagger UI for Express
- CORS - Cross-Origin Resource Sharing middleware
- compression - Response compression middleware
- express-rate-limit - Rate limiting middleware
- express-validator - Request validation middleware
- Joi - Schema validation library
- Nodemailer - Email sending library
- Twilio - Cloud communications platform
- Google Cloud Storage - Object storage service
- Multer - File upload middleware
- PM2 - Production process manager for Node.js
- Docker - Containerization platform
- Docker Compose - Multi-container Docker application tool
- Nginx - High-performance web server and reverse proxy
Contributions are welcome! This is an open-source project, and we encourage:
- π Bug reports
- π‘ Feature requests
- π Documentation improvements
- π§ Code contributions
- β Starring the repository
For issues, questions, or contributions, please visit:
- Repository: https://github.com/fullstack-open-source/nodejs-backend-with-sql
- Issues: Open an issue on GitHub
Made with β€οΈ using open-source technologies
This project is free to use, modify, and distribute for any purpose without restrictions.
Copyright (c) 2025 Full Stack Open Source
This project is licensed under the MIT License - see the LICENSE file for details.