project initialization
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
This commit is contained in:
211
docs/deployment/README.md
Normal file
211
docs/deployment/README.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Deployment Documentation
|
||||
|
||||
This directory contains comprehensive deployment guides for the Multi-Tenant SaaS Platform for Malaysian SMEs.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Getting Started](./getting-started.md) - Quick start and prerequisites
|
||||
- [Development Setup](./development-setup.md) - Local development environment
|
||||
- [Production Deployment](./production-deployment.md) - Production deployment guide
|
||||
- [Docker Deployment](./docker-deployment.md) - Container-based deployment
|
||||
- [Cloud Deployment](./cloud-deployment.md) - Cloud platform deployment
|
||||
- [Monitoring and Maintenance](./monitoring.md) - System monitoring and maintenance
|
||||
|
||||
## Deployment Options
|
||||
|
||||
### 1. Local Development
|
||||
- Quick setup for development and testing
|
||||
- Full environment with all services
|
||||
- Ideal for development and demonstration
|
||||
|
||||
### 2. Docker Container
|
||||
- Containerized deployment
|
||||
- Consistent environments
|
||||
- Easy scaling and management
|
||||
|
||||
### 3. Cloud Platform
|
||||
- AWS, Azure, or Google Cloud deployment
|
||||
- Scalable and production-ready
|
||||
- Managed services and monitoring
|
||||
|
||||
### 4. Hybrid Deployment
|
||||
- Mix of cloud and on-premises
|
||||
- Custom deployment scenarios
|
||||
- Advanced configuration options
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### System Requirements
|
||||
- Linux/Unix-based operating system
|
||||
- Minimum 8GB RAM (16GB recommended)
|
||||
- 4 CPU cores (8 recommended)
|
||||
- 100GB storage space
|
||||
- PostgreSQL 13+
|
||||
- Redis 6+
|
||||
- Node.js 16+
|
||||
|
||||
### Software Requirements
|
||||
- Docker (for container deployment)
|
||||
- Kubernetes (for orchestration)
|
||||
- Git for version control
|
||||
- SSL certificates for production
|
||||
- Domain name configuration
|
||||
|
||||
### Malaysian Requirements
|
||||
- Malaysian data center compliance
|
||||
- PDPA data protection measures
|
||||
- Local timezone configuration
|
||||
- Malaysian payment gateway setup
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Clone Repository**
|
||||
```bash
|
||||
git clone https://github.com/your-org/multi-tenant-saas.git
|
||||
cd multi-tenant-saas
|
||||
```
|
||||
|
||||
2. **Install Dependencies**
|
||||
```bash
|
||||
./scripts/install-dependencies.sh
|
||||
```
|
||||
|
||||
3. **Configure Environment**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your configuration
|
||||
```
|
||||
|
||||
4. **Run Database Migrations**
|
||||
```bash
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
5. **Start Services**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Components
|
||||
- **Backend**: Django REST API with PostgreSQL
|
||||
- **Frontend**: React.js application
|
||||
- **Database**: PostgreSQL with Row-Level Security
|
||||
- **Cache**: Redis for caching and sessions
|
||||
- **Queue**: Celery for background tasks
|
||||
- **Storage**: S3-compatible storage
|
||||
- **Monitoring**: Prometheus and Grafana
|
||||
|
||||
### Multi-Tenant Architecture
|
||||
- Schema-based multi-tenancy
|
||||
- Row-level security
|
||||
- Tenant isolation
|
||||
- Shared infrastructure
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Data Protection
|
||||
- PDPA compliance for Malaysian data
|
||||
- Encryption at rest and in transit
|
||||
- Regular security audits
|
||||
- Access control and authentication
|
||||
|
||||
### Network Security
|
||||
- Firewall configuration
|
||||
- SSL/TLS encryption
|
||||
- VPN access for management
|
||||
- Intrusion detection
|
||||
|
||||
### Application Security
|
||||
- Regular security updates
|
||||
- Vulnerability scanning
|
||||
- Code security reviews
|
||||
- Dependency management
|
||||
|
||||
## Backup and Recovery
|
||||
|
||||
### Backup Strategy
|
||||
- Daily automated backups
|
||||
- Database snapshots
|
||||
- File system backups
|
||||
- Off-site backup storage
|
||||
|
||||
### Recovery Procedures
|
||||
- Disaster recovery plan
|
||||
- Backup restoration procedures
|
||||
- Data integrity verification
|
||||
- Failover testing
|
||||
|
||||
## Monitoring and Logging
|
||||
|
||||
### System Monitoring
|
||||
- Resource utilization
|
||||
- Application performance
|
||||
- Database performance
|
||||
- Network monitoring
|
||||
|
||||
### Application Logging
|
||||
- Structured logging
|
||||
- Error tracking
|
||||
- Performance metrics
|
||||
- User activity logging
|
||||
|
||||
### Alerting
|
||||
- System alerts
|
||||
- Application errors
|
||||
- Performance thresholds
|
||||
- Security incidents
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Database Optimization
|
||||
- Query optimization
|
||||
- Index management
|
||||
- Connection pooling
|
||||
- Database caching
|
||||
|
||||
### Application Optimization
|
||||
- Code optimization
|
||||
- Caching strategies
|
||||
- Load balancing
|
||||
- CDN integration
|
||||
|
||||
### Infrastructure Optimization
|
||||
- Server scaling
|
||||
- Network optimization
|
||||
- Storage optimization
|
||||
- Resource allocation
|
||||
|
||||
## Support and Maintenance
|
||||
|
||||
### Regular Maintenance
|
||||
- Security updates
|
||||
- Performance tuning
|
||||
- Database maintenance
|
||||
- Log rotation
|
||||
|
||||
### Support Procedures
|
||||
- Issue tracking
|
||||
- Bug fixes
|
||||
- Feature requests
|
||||
- User support
|
||||
|
||||
### Documentation
|
||||
- User guides
|
||||
- API documentation
|
||||
- Troubleshooting guides
|
||||
- Best practices
|
||||
|
||||
## Getting Help
|
||||
|
||||
### Resources
|
||||
- Documentation: https://docs.yourplatform.com
|
||||
- Community: https://community.yourplatform.com
|
||||
- Support: support@yourplatform.com
|
||||
- Status: https://status.yourplatform.com
|
||||
|
||||
### Emergency Contact
|
||||
- Critical issues: emergency@yourplatform.com
|
||||
- Security incidents: security@yourplatform.com
|
||||
- Data breaches: privacy@yourplatform.com
|
||||
920
docs/deployment/docker-deployment.md
Normal file
920
docs/deployment/docker-deployment.md
Normal file
@@ -0,0 +1,920 @@
|
||||
# Docker Deployment Guide
|
||||
|
||||
This guide provides comprehensive instructions for deploying the Multi-Tenant SaaS Platform using Docker containers.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### System Requirements
|
||||
- **OS**: Linux (Ubuntu 20.04+ recommended)
|
||||
- **RAM**: 8GB+ (16GB recommended for production)
|
||||
- **CPU**: 4+ cores (8+ recommended for production)
|
||||
- **Storage**: 50GB+ (100GB+ recommended for production)
|
||||
- **Docker**: 20.10+
|
||||
- **Docker Compose**: 1.29+
|
||||
- **SSL**: Valid SSL certificate for production
|
||||
|
||||
### Malaysian Requirements
|
||||
- **Domain**: Malaysian domain name
|
||||
- **SSL**: Valid SSL certificate
|
||||
- **Data Center**: Malaysian cloud region recommended
|
||||
- **Payment Gateway**: Malaysian payment provider credentials
|
||||
- **Compliance**: PDPA compliance configuration
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Install Docker and Docker Compose
|
||||
```bash
|
||||
# Update system packages
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
|
||||
# Add user to docker group
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# Install Docker Compose
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Log out and log back in for group changes to take effect
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
### 2. Clone Repository
|
||||
```bash
|
||||
git clone https://github.com/your-org/multi-tenant-saas.git
|
||||
cd multi-tenant-saas
|
||||
```
|
||||
|
||||
### 3. Configure Environment
|
||||
```bash
|
||||
# Copy environment files
|
||||
cp .env.example .env
|
||||
cp frontend/.env.example frontend/.env
|
||||
|
||||
# Edit environment variables
|
||||
vim .env
|
||||
vim frontend/.env
|
||||
```
|
||||
|
||||
### 4. Start Services
|
||||
```bash
|
||||
# Build and start all services
|
||||
docker-compose up -d --build
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### 1. Production Configuration
|
||||
```bash
|
||||
# Create production directory
|
||||
mkdir -p /opt/multi-tenant-saas
|
||||
cd /opt/multi-tenant-saas
|
||||
|
||||
# Clone repository
|
||||
git clone https://github.com/your-org/multi-tenant-saas.git .
|
||||
|
||||
# Copy production compose file
|
||||
cp docker-compose.yml docker-compose.override.yml
|
||||
```
|
||||
|
||||
### 2. Production Docker Compose
|
||||
```bash
|
||||
# Create production docker-compose.yml
|
||||
vim docker-compose.yml
|
||||
```
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL Database
|
||||
db:
|
||||
image: postgres:13
|
||||
environment:
|
||||
POSTGRES_DB: multi_tenant_saas_prod
|
||||
POSTGRES_USER: multi_tenant_prod_user
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./backups:/backups
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U multi_tenant_prod_user -d multi_tenant_saas_prod"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Redis Cache
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
command: redis-server --appendonly yes
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Django Backend
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.backend
|
||||
environment:
|
||||
- DEBUG=False
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
- DATABASE_URL=postgresql://multi_tenant_prod_user:${DB_PASSWORD}@db:5432/multi_tenant_saas_prod
|
||||
- REDIS_URL=redis://redis:6379/0
|
||||
- ALLOWED_HOSTS=${DOMAIN_NAME},www.${DOMAIN_NAME}
|
||||
- CORS_ALLOWED_ORIGINS=https://${DOMAIN_NAME},https://www.${DOMAIN_NAME}
|
||||
- TIMEZONE=Asia/Kuala_Lumpur
|
||||
- CURRENCY=MYR
|
||||
- SST_RATE=0.06
|
||||
volumes:
|
||||
- staticfiles:/app/staticfiles
|
||||
- media:/app/media
|
||||
- logs:/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "manage.py", "health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# React Frontend
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.frontend
|
||||
environment:
|
||||
- REACT_APP_API_URL=https://${DOMAIN_NAME}/api
|
||||
- REACT_APP_WS_URL=wss://${DOMAIN_NAME}/ws
|
||||
- REACT_APP_ENVIRONMENT=production
|
||||
depends_on:
|
||||
- backend
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Nginx Reverse Proxy
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./ssl:/etc/nginx/ssl:ro
|
||||
- staticfiles:/var/www/static
|
||||
- media:/var/www/media
|
||||
depends_on:
|
||||
- backend
|
||||
- frontend
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Celery Worker
|
||||
celery:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.backend
|
||||
command: celery -A config worker --loglevel=info
|
||||
environment:
|
||||
- DEBUG=False
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
- DATABASE_URL=postgresql://multi_tenant_prod_user:${DB_PASSWORD}@db:5432/multi_tenant_saas_prod
|
||||
- REDIS_URL=redis://redis:6379/0
|
||||
volumes:
|
||||
- logs:/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Celery Beat (Scheduler)
|
||||
celery-beat:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.backend
|
||||
command: celery -A config beat --loglevel=info
|
||||
environment:
|
||||
- DEBUG=False
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
- DATABASE_URL=postgresql://multi_tenant_prod_user:${DB_PASSWORD}@db:5432/multi_tenant_saas_prod
|
||||
- REDIS_URL=redis://redis:6379/0
|
||||
volumes:
|
||||
- logs:/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Flower (Celery Monitoring)
|
||||
flower:
|
||||
image: mher/flower:0.9.7
|
||||
environment:
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- FLOWER_PORT=5555
|
||||
ports:
|
||||
- "5555:5555"
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
- app-network
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
staticfiles:
|
||||
driver: local
|
||||
media:
|
||||
driver: local
|
||||
logs:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
```
|
||||
|
||||
### 3. Create Dockerfiles
|
||||
|
||||
#### Backend Dockerfile
|
||||
```bash
|
||||
# Create backend Dockerfile
|
||||
vim Dockerfile.backend
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# Backend Dockerfile
|
||||
FROM python:3.9-slim
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create app user
|
||||
RUN groupadd -r app && useradd -r -g app app
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy requirements first for better layer caching
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p staticfiles media logs
|
||||
|
||||
# Set correct permissions
|
||||
RUN chown -R app:app /app
|
||||
|
||||
# Switch to app user
|
||||
USER app
|
||||
|
||||
# Collect static files
|
||||
RUN python manage.py collectstatic --noinput
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD python manage.py health
|
||||
|
||||
# Start application
|
||||
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "config.wsgi:application"]
|
||||
```
|
||||
|
||||
#### Frontend Dockerfile
|
||||
```bash
|
||||
# Create frontend Dockerfile
|
||||
vim Dockerfile.frontend
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# Frontend Dockerfile
|
||||
FROM node:16-alpine as build
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY frontend/package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY frontend/ .
|
||||
|
||||
# Build application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy built application
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
||||
|
||||
# Copy nginx configuration
|
||||
COPY nginx-default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Expose port
|
||||
EXPOSE 80
|
||||
|
||||
# Start nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
### 4. Nginx Configuration
|
||||
```bash
|
||||
# Create nginx configuration
|
||||
vim nginx.conf
|
||||
```
|
||||
|
||||
```nginx
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream backend {
|
||||
server backend:8000;
|
||||
}
|
||||
|
||||
upstream frontend {
|
||||
server frontend:80;
|
||||
}
|
||||
|
||||
# HTTP redirect to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name ${DOMAIN_NAME} www.${DOMAIN_NAME};
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
# HTTPS server
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name ${DOMAIN_NAME} www.${DOMAIN_NAME};
|
||||
|
||||
# SSL configuration
|
||||
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
|
||||
# Static files
|
||||
location /static/ {
|
||||
alias /var/www/static/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Media files
|
||||
location /media/ {
|
||||
alias /var/www/media/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# Frontend
|
||||
location / {
|
||||
proxy_pass http://frontend;
|
||||
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;
|
||||
}
|
||||
|
||||
# API
|
||||
location /api/ {
|
||||
proxy_pass http://backend;
|
||||
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;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# WebSocket
|
||||
location /ws/ {
|
||||
proxy_pass http://backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health/ {
|
||||
proxy_pass http://backend;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Environment Variables
|
||||
```bash
|
||||
# Create .env file
|
||||
vim .env
|
||||
```
|
||||
|
||||
```bash
|
||||
# Database
|
||||
DB_PASSWORD=your-secure-database-password
|
||||
|
||||
# Application
|
||||
SECRET_KEY=your-production-secret-key-here
|
||||
DOMAIN_NAME=your-domain.com
|
||||
|
||||
# Malaysian Configuration
|
||||
TIMEZONE=Asia/Kuala_Lumpur
|
||||
CURRENCY=MYR
|
||||
SST_RATE=0.06
|
||||
DEFAULT_COUNTRY=Malaysia
|
||||
|
||||
# Payment Gateways
|
||||
TOUCH_N_GO_API_KEY=your-touch-n-go-api-key
|
||||
TOUCH_N_GO_SECRET=your-touch-n-go-secret
|
||||
GRABPAY_API_KEY=your-grabpay-api-key
|
||||
GRABPAY_SECRET=your-grabpay-secret
|
||||
|
||||
# Email Configuration
|
||||
EMAIL_HOST=smtp.your-email-provider.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_HOST_USER=your-email@domain.com
|
||||
EMAIL_HOST_PASSWORD=your-email-password
|
||||
|
||||
# Security
|
||||
DJANGO_SETTINGS_MODULE=config.production
|
||||
SECURE_BROWSER_XSS_FILTER=True
|
||||
SECURE_CONTENT_TYPE_NOSNIFF=True
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS=True
|
||||
SECURE_HSTS_PRELOAD=True
|
||||
SECURE_HSTS_SECONDS=31536000
|
||||
SECURE_SSL_REDIRECT=True
|
||||
SESSION_COOKIE_SECURE=True
|
||||
CSRF_COOKIE_SECURE=True
|
||||
```
|
||||
|
||||
## SSL Certificate Setup
|
||||
|
||||
### 1. Using Let's Encrypt
|
||||
```bash
|
||||
# Create SSL directory
|
||||
mkdir -p ssl
|
||||
|
||||
# Obtain SSL certificate
|
||||
docker run --rm -p 80:80 -p 443:443 \
|
||||
-v $(pwd)/ssl:/etc/letsencrypt \
|
||||
certbot/certbot certonly --standalone \
|
||||
-d your-domain.com -d www.your-domain.com
|
||||
|
||||
# Copy certificates
|
||||
cp ssl/live/your-domain.com/fullchain.pem ssl/cert.pem
|
||||
cp ssl/live/your-domain.com/privkey.pem ssl/key.pem
|
||||
|
||||
# Set up auto-renewal
|
||||
# Create renewal script
|
||||
vim scripts/renew-ssl.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
docker run --rm \
|
||||
-v $(pwd)/ssl:/etc/letsencrypt \
|
||||
certbot/certbot renew --nginx
|
||||
|
||||
# Copy renewed certificates
|
||||
cp ssl/live/your-domain.com/fullchain.pem ssl/cert.pem
|
||||
cp ssl/live/your-domain.com/privkey.pem ssl/key.pem
|
||||
|
||||
# Reload nginx
|
||||
docker-compose exec nginx nginx -s reload
|
||||
```
|
||||
|
||||
```bash
|
||||
# Make script executable
|
||||
chmod +x scripts/renew-ssl.sh
|
||||
|
||||
# Add to crontab
|
||||
0 0 1 * * /opt/multi-tenant-saas/scripts/renew-ssl.sh
|
||||
```
|
||||
|
||||
## Malaysian Configuration
|
||||
|
||||
### 1. Payment Gateway Setup
|
||||
```bash
|
||||
# Create payment configuration
|
||||
vim config/payments.py
|
||||
```
|
||||
|
||||
```python
|
||||
PAYMENT_GATEWAYS = {
|
||||
'touch_n_go': {
|
||||
'enabled': True,
|
||||
'environment': 'production',
|
||||
'api_key': os.environ.get('TOUCH_N_GO_API_KEY'),
|
||||
'secret': os.environ.get('TOUCH_N_GO_SECRET'),
|
||||
'merchant_id': os.environ.get('TOUCH_N_GO_MERCHANT_ID'),
|
||||
'currency': 'MYR',
|
||||
'country': 'MY',
|
||||
},
|
||||
'grabpay': {
|
||||
'enabled': True,
|
||||
'environment': 'production',
|
||||
'api_key': os.environ.get('GRABPAY_API_KEY'),
|
||||
'secret': os.environ.get('GRABPAY_SECRET'),
|
||||
'merchant_id': os.environ.get('GRABPAY_MERCHANT_ID'),
|
||||
'currency': 'MYR',
|
||||
'country': 'MY',
|
||||
},
|
||||
'online_banking': {
|
||||
'enabled': True,
|
||||
'banks': [
|
||||
{'code': 'maybank2u', 'name': 'Maybank2u'},
|
||||
{'code': 'cimb_clicks', 'name': 'CIMB Clicks'},
|
||||
{'code': 'rhbb', 'name': 'RHB Banking'},
|
||||
],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. SST Configuration
|
||||
```bash
|
||||
# Create SST configuration
|
||||
vim config/sst.py
|
||||
```
|
||||
|
||||
```python
|
||||
SST_SETTINGS = {
|
||||
'enabled': True,
|
||||
'rate': 0.06,
|
||||
'registration_number': os.environ.get('SST_REGISTRATION_NUMBER'),
|
||||
'currency': 'MYR',
|
||||
'invoice_prefix': 'SST',
|
||||
'tax_inclusive': True,
|
||||
'exempt_categories': [
|
||||
'education',
|
||||
'healthcare',
|
||||
'financial_services',
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
## Production Deployment Steps
|
||||
|
||||
### 1. Build and Start Services
|
||||
```bash
|
||||
# Build images
|
||||
docker-compose build
|
||||
|
||||
# Start services
|
||||
docker-compose up -d
|
||||
|
||||
# Check status
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 2. Initialize Database
|
||||
```bash
|
||||
# Run migrations
|
||||
docker-compose exec backend python manage.py migrate
|
||||
|
||||
# Create superuser
|
||||
docker-compose exec backend python manage.py createsuperuser
|
||||
|
||||
# Load initial data
|
||||
docker-compose exec backend python manage.py load_initial_data
|
||||
```
|
||||
|
||||
### 3. Verify Deployment
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs backend
|
||||
docker-compose logs frontend
|
||||
|
||||
# Health check
|
||||
curl -f https://your-domain.com/health/
|
||||
|
||||
# Access application
|
||||
# Frontend: https://your-domain.com
|
||||
# API: https://your-domain.com/api
|
||||
# Admin: https://your-domain.com/admin
|
||||
# Flower: https://your-domain.com:5555
|
||||
```
|
||||
|
||||
## Monitoring and Logging
|
||||
|
||||
### 1. Container Monitoring
|
||||
```bash
|
||||
# View container status
|
||||
docker-compose ps
|
||||
|
||||
# View resource usage
|
||||
docker stats
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f backend
|
||||
docker-compose logs -f frontend
|
||||
docker-compose logs -f celery
|
||||
```
|
||||
|
||||
### 2. Health Checks
|
||||
```bash
|
||||
# Application health
|
||||
curl -f https://your-domain.com/health/
|
||||
|
||||
# Database health
|
||||
docker-compose exec db pg_isready -U multi_tenant_prod_user -d multi_tenant_saas_prod
|
||||
|
||||
# Redis health
|
||||
docker-compose exec redis redis-cli ping
|
||||
```
|
||||
|
||||
### 3. Log Management
|
||||
```bash
|
||||
# View aggregated logs
|
||||
docker-compose logs --tail=100
|
||||
|
||||
# Access container logs
|
||||
docker-compose exec backend tail -f logs/app.log
|
||||
|
||||
# Configure log rotation
|
||||
# Add to docker-compose.yml for each service
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
## Backup and Recovery
|
||||
|
||||
### 1. Database Backup
|
||||
```bash
|
||||
# Create backup script
|
||||
vim scripts/backup-database.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR="/opt/multi-tenant-saas/backups"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/database_backup_$DATE.sql"
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Create database backup
|
||||
docker-compose exec -T db pg_dump -U multi_tenant_prod_user -d multi_tenant_saas_prod > $BACKUP_FILE
|
||||
|
||||
# Compress backup
|
||||
gzip $BACKUP_FILE
|
||||
|
||||
# Keep only last 30 days of backups
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||||
|
||||
echo "Database backup completed: $BACKUP_FILE.gz"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Make script executable
|
||||
chmod +x scripts/backup-database.sh
|
||||
|
||||
# Set up cron job for daily backups
|
||||
0 2 * * * /opt/multi-tenant-saas/scripts/backup-database.sh
|
||||
```
|
||||
|
||||
### 2. Volume Backup
|
||||
```bash
|
||||
# Backup all volumes
|
||||
docker run --rm \
|
||||
-v multi_tenant_saas_postgres_data:/source \
|
||||
-v $(pwd)/backups:/backup \
|
||||
alpine tar czf /backup/postgres_data_$(date +%Y%m%d).tar.gz -C /source .
|
||||
|
||||
docker run --rm \
|
||||
-v multi_tenant_saas_redis_data:/source \
|
||||
-v $(pwd)/backups:/backup \
|
||||
alpine tar czf /backup/redis_data_$(date +%Y%m%d).tar.gz -C /source .
|
||||
```
|
||||
|
||||
## Security Hardening
|
||||
|
||||
### 1. Container Security
|
||||
```bash
|
||||
# Update base images regularly
|
||||
docker-compose pull
|
||||
|
||||
# Use specific image versions
|
||||
# Avoid using 'latest' tag
|
||||
|
||||
# Run containers as non-root users
|
||||
# Already configured in Dockerfiles
|
||||
|
||||
# Limit container capabilities
|
||||
# Add to docker-compose.yml
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- SETGID
|
||||
- SETUID
|
||||
- NET_BIND_SERVICE
|
||||
```
|
||||
|
||||
### 2. Network Security
|
||||
```bash
|
||||
# Use custom networks
|
||||
# Already configured in docker-compose.yml
|
||||
|
||||
# Isolate sensitive services
|
||||
# Database is not exposed to host
|
||||
|
||||
# Use internal networks for service communication
|
||||
# All services use app-network
|
||||
```
|
||||
|
||||
### 3. Environment Variable Security
|
||||
```bash
|
||||
# Use Docker secrets for sensitive data
|
||||
# Create secrets file
|
||||
echo "your-secret-key" | docker secret create secret_key -
|
||||
|
||||
# Use secrets in docker-compose.yml
|
||||
secrets:
|
||||
secret_key:
|
||||
external: true
|
||||
```
|
||||
|
||||
## Scaling and Performance
|
||||
|
||||
### 1. Horizontal Scaling
|
||||
```bash
|
||||
# Scale backend services
|
||||
docker-compose up -d --scale backend=4
|
||||
|
||||
# Use load balancer for multiple instances
|
||||
# Update nginx upstream configuration
|
||||
```
|
||||
|
||||
### 2. Resource Limits
|
||||
```yaml
|
||||
# Add to docker-compose.yml
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
### 3. Caching Strategy
|
||||
```bash
|
||||
# Use Redis for caching
|
||||
# Already configured in docker-compose.yml
|
||||
|
||||
# Configure Django cache settings
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
|
||||
'LOCATION': 'redis://redis:6379/1',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Container fails to start**
|
||||
```bash
|
||||
# Check container logs
|
||||
docker-compose logs backend
|
||||
docker-compose logs frontend
|
||||
|
||||
# Check container status
|
||||
docker-compose ps
|
||||
|
||||
# Restart specific service
|
||||
docker-compose restart backend
|
||||
```
|
||||
|
||||
2. **Database connection issues**
|
||||
```bash
|
||||
# Check database health
|
||||
docker-compose exec db pg_isready
|
||||
|
||||
# Check network connectivity
|
||||
docker-compose exec backend ping db
|
||||
|
||||
# Verify environment variables
|
||||
docker-compose exec backend env | grep DATABASE
|
||||
```
|
||||
|
||||
3. **SSL certificate issues**
|
||||
```bash
|
||||
# Check certificate validity
|
||||
openssl x509 -in ssl/cert.pem -text -noout
|
||||
|
||||
# Test SSL connection
|
||||
openssl s_client -connect your-domain.com:443 -servername your-domain.com
|
||||
```
|
||||
|
||||
4. **Performance issues**
|
||||
```bash
|
||||
# Check resource usage
|
||||
docker stats
|
||||
|
||||
# Monitor database performance
|
||||
docker-compose exec db top
|
||||
|
||||
# Check slow queries
|
||||
docker-compose exec db psql -c "SELECT query, mean_time, calls FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 10;"
|
||||
```
|
||||
|
||||
## Production Checklist
|
||||
|
||||
- [ ] Docker and Docker Compose installed
|
||||
- [ ] Repository cloned and configured
|
||||
- [ ] SSL certificate obtained and configured
|
||||
- [ ] Environment variables set correctly
|
||||
- [ ] Docker Compose file configured for production
|
||||
- [ ] Security hardening applied
|
||||
- [ ] Malaysian payment gateways configured
|
||||
- [ ] SST configuration completed
|
||||
- [ ] Database initialized with production data
|
||||
- [ ] Health checks passing
|
||||
- [ ] Monitoring and logging configured
|
||||
- [ ] Backup procedures implemented
|
||||
- [ ] Security testing completed
|
||||
- [ ] Performance testing completed
|
||||
- [ ] Load testing performed
|
||||
- [ ] Disaster recovery plan in place
|
||||
|
||||
## Support Resources
|
||||
|
||||
- **Documentation**: https://docs.yourplatform.com
|
||||
- **GitHub Issues**: https://github.com/your-org/multi-tenant-saas/issues
|
||||
- **Community**: https://community.yourplatform.com
|
||||
- **Support**: support@yourplatform.com
|
||||
- **Emergency**: emergency@yourplatform.com
|
||||
369
docs/deployment/getting-started.md
Normal file
369
docs/deployment/getting-started.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# Getting Started Guide
|
||||
|
||||
This guide will help you get the Multi-Tenant SaaS Platform up and running quickly.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### System Requirements
|
||||
- **OS**: Linux/Unix (Ubuntu 20.04+ recommended)
|
||||
- **RAM**: Minimum 8GB (16GB recommended)
|
||||
- **CPU**: 4 cores (8 cores recommended)
|
||||
- **Storage**: 100GB free space
|
||||
- **Network**: Stable internet connection
|
||||
|
||||
### Software Requirements
|
||||
- **Python**: 3.9+
|
||||
- **Node.js**: 16+
|
||||
- **PostgreSQL**: 13+
|
||||
- **Redis**: 6+
|
||||
- **Docker**: 20.10+ (optional)
|
||||
- **Git**: Latest version
|
||||
|
||||
### Malaysian Specific Requirements
|
||||
- **Domain**: Registered domain name
|
||||
- **SSL**: SSL certificate for HTTPS
|
||||
- **Payment Gateway**: Malaysian payment provider account
|
||||
- **Data Center**: Malaysian data center or cloud region
|
||||
|
||||
## Quick Setup
|
||||
|
||||
### 1. Clone the Repository
|
||||
```bash
|
||||
git clone https://github.com/your-org/multi-tenant-saas.git
|
||||
cd multi-tenant-saas
|
||||
```
|
||||
|
||||
### 2. Install System Dependencies
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update
|
||||
sudo apt install -y python3-pip python3-venv nodejs npm postgresql redis-server
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo yum install -y python3-pip nodejs npm postgresql-server redis
|
||||
```
|
||||
|
||||
### 3. Create Virtual Environment
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
### 4. Install Python Dependencies
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-dev.txt
|
||||
```
|
||||
|
||||
### 5. Install Node Dependencies
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
cd ..
|
||||
```
|
||||
|
||||
### 6. Configure Environment
|
||||
```bash
|
||||
cp .env.example .env
|
||||
cp frontend/.env.example frontend/.env
|
||||
```
|
||||
|
||||
Edit the `.env` files with your configuration:
|
||||
|
||||
```bash
|
||||
# Backend .env
|
||||
DEBUG=False
|
||||
SECRET_KEY=your-secret-key-here
|
||||
DATABASE_URL=postgresql://user:password@localhost:5432/multi_tenant_saas
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
ALLOWED_HOSTS=localhost,your-domain.com
|
||||
CORS_ALLOWED_ORIGINS=http://localhost:3000,https://your-domain.com
|
||||
|
||||
# Malaysian Configuration
|
||||
TIMEZONE=Asia/Kuala_Lumpur
|
||||
CURRENCY=MYR
|
||||
SST_RATE=0.06
|
||||
DEFAULT_COUNTRY=Malaysia
|
||||
```
|
||||
|
||||
### 7. Set Up Database
|
||||
```bash
|
||||
# Create database
|
||||
sudo -u postgres createdb multi_tenant_saas
|
||||
sudo -u postgres createuser multi_tenant_user
|
||||
|
||||
# Set database password
|
||||
sudo -u postgres psql -c "ALTER USER multi_tenant_user PASSWORD 'your-password';"
|
||||
|
||||
# Run migrations
|
||||
python manage.py migrate
|
||||
|
||||
# Create superuser
|
||||
python manage.py createsuperuser
|
||||
```
|
||||
|
||||
### 8. Set Up Redis
|
||||
```bash
|
||||
# Start Redis service
|
||||
sudo systemctl start redis
|
||||
sudo systemctl enable redis
|
||||
```
|
||||
|
||||
### 9. Load Initial Data
|
||||
```bash
|
||||
# Load initial data
|
||||
python manage.py load_initial_data
|
||||
|
||||
# Create sample tenant
|
||||
python manage.py create_sample_tenant
|
||||
```
|
||||
|
||||
### 10. Start Development Servers
|
||||
```bash
|
||||
# Start backend
|
||||
python manage.py runserver
|
||||
|
||||
# In another terminal, start frontend
|
||||
cd frontend
|
||||
npm start
|
||||
```
|
||||
|
||||
### 11. Access the Application
|
||||
- Frontend: http://localhost:3000
|
||||
- Backend API: http://localhost:8000
|
||||
- Admin Panel: http://localhost:8000/admin/
|
||||
|
||||
## Docker Quick Start
|
||||
|
||||
### 1. Using Docker Compose
|
||||
```bash
|
||||
# Copy environment files
|
||||
cp .env.example .env
|
||||
cp frontend/.env.example frontend/.env
|
||||
|
||||
# Start all services
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 2. Access Services
|
||||
- Frontend: http://localhost:3000
|
||||
- Backend API: http://localhost:8000
|
||||
- PostgreSQL: localhost:5432
|
||||
- Redis: localhost:6379
|
||||
|
||||
## Production Setup
|
||||
|
||||
### 1. Environment Configuration
|
||||
```bash
|
||||
# Production environment
|
||||
cp .env.production .env
|
||||
cp frontend/.env.production frontend/.env
|
||||
|
||||
# Edit with production settings
|
||||
vim .env
|
||||
vim frontend/.env
|
||||
```
|
||||
|
||||
### 2. Database Setup
|
||||
```bash
|
||||
# Production database
|
||||
sudo -u postgres createdb multi_tenant_saas_prod
|
||||
sudo -u postgres createuser multi_tenant_prod_user
|
||||
|
||||
# Set strong password
|
||||
sudo -u postgres psql -c "ALTER USER multi_tenant_prod_user PASSWORD 'strong-password';"
|
||||
|
||||
# Run production migrations
|
||||
python manage.py migrate --settings=config.production
|
||||
```
|
||||
|
||||
### 3. SSL Configuration
|
||||
```bash
|
||||
# Install Certbot
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
|
||||
# Obtain SSL certificate
|
||||
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
||||
```
|
||||
|
||||
### 4. Web Server Setup
|
||||
```bash
|
||||
# Install Nginx
|
||||
sudo apt install nginx
|
||||
|
||||
# Configure Nginx
|
||||
sudo cp deployment/nginx.conf /etc/nginx/sites-available/multi-tenant-saas
|
||||
sudo ln -s /etc/nginx/sites-available/multi-tenant-saas /etc/nginx/sites-enabled/
|
||||
|
||||
# Test and restart Nginx
|
||||
sudo nginx -t
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
### 5. Process Management
|
||||
```bash
|
||||
# Install Gunicorn
|
||||
pip install gunicorn
|
||||
|
||||
# Create systemd service
|
||||
sudo cp deployment/gunicorn.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable gunicorn
|
||||
sudo systemctl start gunicorn
|
||||
```
|
||||
|
||||
## Malaysian Configuration
|
||||
|
||||
### 1. Payment Gateway Setup
|
||||
```bash
|
||||
# Configure Malaysian payment gateways
|
||||
# Edit settings/local.py or environment variables
|
||||
|
||||
PAYMENT_GATEWAYS = {
|
||||
'touch_n_go': {
|
||||
'enabled': True,
|
||||
'api_key': 'your-touch-n-go-api-key',
|
||||
'secret': 'your-touch-n-go-secret'
|
||||
},
|
||||
'grabpay': {
|
||||
'enabled': True,
|
||||
'api_key': 'your-grabpay-api-key',
|
||||
'secret': 'your-grabpay-secret'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Timezone Configuration
|
||||
```bash
|
||||
# Set Malaysian timezone
|
||||
sudo timedatectl set-timezone Asia/Kuala_Lumpur
|
||||
```
|
||||
|
||||
### 3. SST Configuration
|
||||
```bash
|
||||
# Configure SST settings
|
||||
SST_SETTINGS = {
|
||||
'rate': 0.06,
|
||||
'enabled': True,
|
||||
'tax_id': 'your-sst-registration-number'
|
||||
}
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
### 1. Health Checks
|
||||
```bash
|
||||
# Backend health check
|
||||
curl http://localhost:8000/health/
|
||||
|
||||
# Database connectivity
|
||||
python manage.py dbshell --command="SELECT 1;"
|
||||
|
||||
# Redis connectivity
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
### 2. Application Testing
|
||||
```bash
|
||||
# Run tests
|
||||
python manage.py test
|
||||
|
||||
# Frontend tests
|
||||
cd frontend
|
||||
npm test
|
||||
```
|
||||
|
||||
### 3. Production Readiness
|
||||
```bash
|
||||
# Check security
|
||||
python manage.py check --deploy
|
||||
|
||||
# Check performance
|
||||
python manage.py check --settings=config.performance
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Database Connection Errors**
|
||||
```bash
|
||||
# Check PostgreSQL status
|
||||
sudo systemctl status postgresql
|
||||
|
||||
# Check database logs
|
||||
sudo tail -f /var/log/postgresql/postgresql-13-main.log
|
||||
```
|
||||
|
||||
2. **Port Conflicts**
|
||||
```bash
|
||||
# Check running services
|
||||
sudo netstat -tlnp | grep :8000
|
||||
sudo netstat -tlnp | grep :3000
|
||||
```
|
||||
|
||||
3. **Permission Issues**
|
||||
```bash
|
||||
# Fix file permissions
|
||||
sudo chown -R $USER:$USER /path/to/project
|
||||
sudo chmod -R 755 /path/to/project
|
||||
```
|
||||
|
||||
4. **Memory Issues**
|
||||
```bash
|
||||
# Check memory usage
|
||||
free -h
|
||||
|
||||
# Check process memory
|
||||
ps aux --sort=-%mem | head
|
||||
```
|
||||
|
||||
## Support Resources
|
||||
|
||||
### Documentation
|
||||
- API Documentation: `/docs/api/`
|
||||
- Module Documentation: `/docs/modules/`
|
||||
- Deployment Guides: `/docs/deployment/`
|
||||
|
||||
### Community Support
|
||||
- GitHub Issues: https://github.com/your-org/multi-tenant-saas/issues
|
||||
- Community Forum: https://community.yourplatform.com
|
||||
- Discord Server: https://discord.gg/yourplatform
|
||||
|
||||
### Professional Support
|
||||
- Email: support@yourplatform.com
|
||||
- Phone: +60123456789
|
||||
- Emergency: emergency@yourplatform.com
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Customize Modules**: Enable and configure specific industry modules
|
||||
2. **Set Up Monitoring**: Configure monitoring and alerting
|
||||
3. **Configure Backups**: Set up automated backup procedures
|
||||
4. **Deploy to Production**: Follow production deployment guide
|
||||
5. **Configure Security**: Set up SSL, firewall, and security measures
|
||||
|
||||
## Malaysian SME Setup
|
||||
|
||||
### 1. Business Registration
|
||||
- Register your business with SSM
|
||||
- Obtain necessary licenses and permits
|
||||
- Set up business bank account
|
||||
|
||||
### 2. Tax Registration
|
||||
- Register for SST with LHDN
|
||||
- Obtain SST registration number
|
||||
- Set up tax accounting procedures
|
||||
|
||||
### 3. Payment Gateway
|
||||
- Sign up with Malaysian payment providers
|
||||
- Complete KYC verification
|
||||
- Configure payment methods
|
||||
|
||||
### 4. Compliance Setup
|
||||
- PDPA compliance procedures
|
||||
- Data protection policies
|
||||
- Privacy policy creation
|
||||
1026
docs/deployment/monitoring.md
Normal file
1026
docs/deployment/monitoring.md
Normal file
File diff suppressed because it is too large
Load Diff
751
docs/deployment/production-deployment.md
Normal file
751
docs/deployment/production-deployment.md
Normal file
@@ -0,0 +1,751 @@
|
||||
# Production Deployment Guide
|
||||
|
||||
This guide provides comprehensive instructions for deploying the Multi-Tenant SaaS Platform to production environments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Infrastructure Requirements
|
||||
- **Server**: Cloud VPS or dedicated server with minimum specifications
|
||||
- **OS**: Ubuntu 20.04 LTS or CentOS 8+
|
||||
- **RAM**: 16GB+ recommended
|
||||
- **CPU**: 8+ cores recommended
|
||||
- **Storage**: 200GB+ SSD storage
|
||||
- **Network**: 1Gbps+ bandwidth
|
||||
|
||||
### Software Requirements
|
||||
- **Python**: 3.9+
|
||||
- **Node.js**: 16+
|
||||
- **PostgreSQL**: 13+
|
||||
- **Redis**: 6+
|
||||
- **Nginx**: 1.18+
|
||||
- **Supervisor**: Process management
|
||||
- **Certbot**: SSL certificates
|
||||
- **Fail2ban**: Security
|
||||
|
||||
### Malaysian Requirements
|
||||
- **Domain**: Malaysian domain (.com.my, .my)
|
||||
- **SSL**: Valid SSL certificate
|
||||
- **Data Center**: Malaysian cloud region
|
||||
- **Payment Gateway**: Malaysian payment providers
|
||||
- **Compliance**: PDPA and KKM compliance
|
||||
|
||||
## Server Preparation
|
||||
|
||||
### 1. System Update and Security
|
||||
```bash
|
||||
# Update system packages
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install security packages
|
||||
sudo apt install -y ufw fail2ban unattended-upgrades
|
||||
|
||||
# Configure firewall
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
sudo ufw allow ssh
|
||||
sudo ufw allow http
|
||||
sudo ufw allow https
|
||||
sudo ufw enable
|
||||
|
||||
# Configure automatic security updates
|
||||
sudo dpkg-reconfigure -plow unattended-upgrades
|
||||
```
|
||||
|
||||
### 2. Create Application User
|
||||
```bash
|
||||
# Create application user
|
||||
sudo adduser --system --group --home /opt/multi-tenant-saas multi-tenant
|
||||
|
||||
# Set up sudo access for deployment
|
||||
sudo visudo
|
||||
# Add: multi-tenant ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart gunicorn, /usr/bin/systemctl restart nginx
|
||||
```
|
||||
|
||||
### 3. Install Required Software
|
||||
```bash
|
||||
# Install Python and development tools
|
||||
sudo apt install -y python3-pip python3-venv python3-dev build-essential
|
||||
|
||||
# Install Node.js
|
||||
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Install PostgreSQL
|
||||
sudo apt install -y postgresql postgresql-contrib
|
||||
|
||||
# Install Redis
|
||||
sudo apt install -y redis-server
|
||||
|
||||
# Install Nginx
|
||||
sudo apt install -y nginx
|
||||
|
||||
# Install Supervisor
|
||||
sudo apt install -y supervisor
|
||||
|
||||
# Install Certbot
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
## Database Setup
|
||||
|
||||
### 1. PostgreSQL Configuration
|
||||
```bash
|
||||
# Configure PostgreSQL
|
||||
sudo -u postgres psql
|
||||
|
||||
# Create database and user
|
||||
CREATE DATABASE multi_tenant_saas_prod;
|
||||
CREATE USER multi_tenant_prod_user WITH PASSWORD 'strong-password-here';
|
||||
GRANT ALL PRIVILEGES ON DATABASE multi_tenant_saas_prod TO multi_tenant_prod_user;
|
||||
ALTER USER multi_tenant_prod_user CREATEDB;
|
||||
|
||||
# Configure PostgreSQL settings
|
||||
sudo vim /etc/postgresql/13/main/postgresql.conf
|
||||
# Update:
|
||||
# shared_buffers = 256MB
|
||||
# effective_cache_size = 1GB
|
||||
# maintenance_work_mem = 64MB
|
||||
# checkpoint_completion_target = 0.9
|
||||
# wal_buffers = 16MB
|
||||
# default_statistics_target = 100
|
||||
# random_page_cost = 1.1
|
||||
# effective_io_concurrency = 200
|
||||
# work_mem = 4MB
|
||||
# min_wal_size = 1GB
|
||||
# max_wal_size = 4GB
|
||||
|
||||
# Restart PostgreSQL
|
||||
sudo systemctl restart postgresql
|
||||
```
|
||||
|
||||
### 2. Redis Configuration
|
||||
```bash
|
||||
# Configure Redis
|
||||
sudo vim /etc/redis/redis.conf
|
||||
# Update:
|
||||
# maxmemory 512mb
|
||||
# maxmemory-policy allkeys-lru
|
||||
# save 900 1
|
||||
# save 300 10
|
||||
# save 60 10000
|
||||
|
||||
# Restart Redis
|
||||
sudo systemctl restart redis
|
||||
```
|
||||
|
||||
## Application Deployment
|
||||
|
||||
### 1. Deploy Application Code
|
||||
```bash
|
||||
# Switch to application user
|
||||
sudo su - multi-tenant
|
||||
|
||||
# Clone repository
|
||||
git clone https://github.com/your-org/multi-tenant-saas.git /opt/multi-tenant-saas
|
||||
cd /opt/multi-tenant-saas
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
pip install gunicorn psycopg2-binary
|
||||
|
||||
# Install frontend dependencies
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
|
||||
# Set up environment
|
||||
cp .env.production .env
|
||||
vim .env
|
||||
```
|
||||
|
||||
### 2. Environment Configuration
|
||||
```bash
|
||||
# Production environment variables
|
||||
DEBUG=False
|
||||
SECRET_KEY=your-production-secret-key-here
|
||||
DATABASE_URL=postgresql://multi_tenant_prod_user:strong-password@localhost:5432/multi_tenant_saas_prod
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
ALLOWED_HOSTS=your-domain.com,www.your-domain.com
|
||||
CORS_ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
|
||||
|
||||
# Malaysian configuration
|
||||
TIMEZONE=Asia/Kuala_Lumpur
|
||||
CURRENCY=MYR
|
||||
SST_RATE=0.06
|
||||
DEFAULT_COUNTRY=Malaysia
|
||||
|
||||
# Security settings
|
||||
SECURE_BROWSER_XSS_FILTER=True
|
||||
SECURE_CONTENT_TYPE_NOSNIFF=True
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS=True
|
||||
SECURE_HSTS_PRELOAD=True
|
||||
SECURE_HSTS_SECONDS=31536000
|
||||
SECURE_SSL_REDIRECT=True
|
||||
SESSION_COOKIE_SECURE=True
|
||||
CSRF_COOKIE_SECURE=True
|
||||
```
|
||||
|
||||
### 3. Database Migrations
|
||||
```bash
|
||||
# Run migrations
|
||||
python manage.py migrate --settings=config.production
|
||||
|
||||
# Create superuser
|
||||
python manage.py createsuperuser --settings=config.production
|
||||
|
||||
# Load initial data
|
||||
python manage.py load_initial_data --settings=config.production
|
||||
|
||||
# Collect static files
|
||||
python manage.py collectstatic --settings=config.production --noinput
|
||||
```
|
||||
|
||||
## Web Server Configuration
|
||||
|
||||
### 1. Nginx Configuration
|
||||
```bash
|
||||
# Create Nginx configuration
|
||||
sudo vim /etc/nginx/sites-available/multi-tenant-saas
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
|
||||
# Static files
|
||||
location /static/ {
|
||||
alias /opt/multi-tenant-saas/staticfiles/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Media files
|
||||
location /media/ {
|
||||
alias /opt/multi-tenant-saas/media/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# Frontend
|
||||
location / {
|
||||
root /opt/multi-tenant-saas/frontend/build;
|
||||
try_files $uri $uri/ /index.html;
|
||||
expires 1h;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# API
|
||||
location /api/ {
|
||||
proxy_pass http://unix:/run/gunicorn.sock;
|
||||
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;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# WebSocket
|
||||
location /ws/ {
|
||||
proxy_pass http://unix:/run/gunicorn.sock;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health/ {
|
||||
proxy_pass http://unix:/run/gunicorn.sock;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Enable Site and Test
|
||||
```bash
|
||||
# Enable site
|
||||
sudo ln -s /etc/nginx/sites-available/multi-tenant-saas /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## Process Management
|
||||
|
||||
### 1. Gunicorn Configuration
|
||||
```bash
|
||||
# Create Gunicorn configuration
|
||||
sudo vim /opt/multi-tenant-saas/gunicorn.conf.py
|
||||
```
|
||||
|
||||
```python
|
||||
bind = 'unix:/run/gunicorn.sock'
|
||||
workers = 4
|
||||
worker_class = 'sync'
|
||||
worker_connections = 1000
|
||||
timeout = 30
|
||||
keepalive = 5
|
||||
max_requests = 1000
|
||||
max_requests_jitter = 100
|
||||
preload_app = True
|
||||
reload = False
|
||||
daemon = False
|
||||
user = 'multi-tenant'
|
||||
group = 'multi-tenant'
|
||||
raw_env = [
|
||||
'DJANGO_SETTINGS_MODULE=config.production',
|
||||
'PYTHONPATH=/opt/multi-tenant-saas',
|
||||
]
|
||||
```
|
||||
|
||||
### 2. Create Systemd Service
|
||||
```bash
|
||||
# Create Gunicorn service
|
||||
sudo vim /etc/systemd/system/gunicorn.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Multi-Tenant SaaS Platform Gunicorn
|
||||
After=network.target postgresql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=multi-tenant
|
||||
Group=multi-tenant
|
||||
WorkingDirectory=/opt/multi-tenant-saas
|
||||
Environment=PATH=/opt/multi-tenant-saas/venv/bin
|
||||
ExecStart=/opt/multi-tenant-saas/venv/bin/gunicorn --config gunicorn.conf.py config.wsgi:application
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
KillMode=mixed
|
||||
TimeoutStopSec=5
|
||||
PrivateTmp=true
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### 3. Enable and Start Services
|
||||
```bash
|
||||
# Enable and start Gunicorn
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable gunicorn
|
||||
sudo systemctl start gunicorn
|
||||
|
||||
# Check status
|
||||
sudo systemctl status gunicorn
|
||||
```
|
||||
|
||||
## SSL Certificate Setup
|
||||
|
||||
### 1. Obtain SSL Certificate
|
||||
```bash
|
||||
# Stop Nginx temporarily
|
||||
sudo systemctl stop nginx
|
||||
|
||||
# Obtain SSL certificate
|
||||
sudo certbot certonly --standalone -d your-domain.com -d www.your-domain.com
|
||||
|
||||
# Start Nginx
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
### 2. Set Up Auto-Renewal
|
||||
```bash
|
||||
# Test auto-renewal
|
||||
sudo certbot renew --dry-run
|
||||
|
||||
# Set up cron job for auto-renewal
|
||||
sudo crontab -e
|
||||
# Add: 0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
## Malaysian Configuration
|
||||
|
||||
### 1. Payment Gateway Setup
|
||||
```bash
|
||||
# Configure Malaysian payment gateways
|
||||
sudo vim /opt/multi-tenant-saas/config/payments.py
|
||||
```
|
||||
|
||||
```python
|
||||
PAYMENT_GATEWAYS = {
|
||||
'touch_n_go': {
|
||||
'enabled': True,
|
||||
'environment': 'production',
|
||||
'api_key': os.environ.get('TOUCH_N_GO_API_KEY'),
|
||||
'secret': os.environ.get('TOUCH_N_GO_SECRET'),
|
||||
'merchant_id': os.environ.get('TOUCH_N_GO_MERCHANT_ID'),
|
||||
},
|
||||
'grabpay': {
|
||||
'enabled': True,
|
||||
'environment': 'production',
|
||||
'api_key': os.environ.get('GRABPAY_API_KEY'),
|
||||
'secret': os.environ.get('GRABPAY_SECRET'),
|
||||
'merchant_id': os.environ.get('GRABPAY_MERCHANT_ID'),
|
||||
},
|
||||
'online_banking': {
|
||||
'enabled': True,
|
||||
'banks': ['maybank2u', 'cimb_clicks', 'rhbb'],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. SST Configuration
|
||||
```bash
|
||||
# Configure SST settings
|
||||
sudo vim /opt/multi-tenant-saas/config/sst.py
|
||||
```
|
||||
|
||||
```python
|
||||
SST_SETTINGS = {
|
||||
'enabled': True,
|
||||
'rate': 0.06,
|
||||
'registration_number': os.environ.get('SST_REGISTRATION_NUMBER'),
|
||||
'currency': 'MYR',
|
||||
'invoice_prefix': 'SST',
|
||||
'tax_inclusive': True,
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Timezone and Localization
|
||||
```bash
|
||||
# Set system timezone
|
||||
sudo timedatectl set-timezone Asia/Kuala_Lumpur
|
||||
|
||||
# Configure application timezone
|
||||
sudo vim /opt/multi-tenant-saas/config/settings.py
|
||||
```
|
||||
|
||||
```python
|
||||
TIME_ZONE = 'Asia/Kuala_Lumpur'
|
||||
LANGUAGE_CODE = 'en-my'
|
||||
USE_I18N = True
|
||||
USE_L10N = True
|
||||
USE_TZ = True
|
||||
```
|
||||
|
||||
## Monitoring and Logging
|
||||
|
||||
### 1. Application Logging
|
||||
```bash
|
||||
# Create log directory
|
||||
sudo mkdir -p /var/log/multi-tenant-saas
|
||||
sudo chown multi-tenant:multi-tenant /var/log/multi-tenant-saas
|
||||
|
||||
# Configure logging
|
||||
sudo vim /opt/multi-tenant-saas/config/logging.py
|
||||
```
|
||||
|
||||
```python
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
||||
'style': '{',
|
||||
},
|
||||
'simple': {
|
||||
'format': '{levelname} {message}',
|
||||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': '/var/log/multi-tenant-saas/django.log',
|
||||
'maxBytes': 10485760, # 10MB
|
||||
'backupCount': 5,
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'console': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'simple',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'django': {
|
||||
'handlers': ['file', 'console'],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
'multi_tenant_saas': {
|
||||
'handlers': ['file', 'console'],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 2. System Monitoring
|
||||
```bash
|
||||
# Install monitoring tools
|
||||
sudo apt install -y htop iotop nethogs
|
||||
|
||||
# Set up log rotation
|
||||
sudo vim /etc/logrotate.d/multi-tenant-saas
|
||||
```
|
||||
|
||||
```
|
||||
/var/log/multi-tenant-saas/*.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 0640 multi-tenant multi-tenant
|
||||
postrotate
|
||||
systemctl reload gunicorn
|
||||
endscript
|
||||
}
|
||||
```
|
||||
|
||||
## Backup and Recovery
|
||||
|
||||
### 1. Database Backup
|
||||
```bash
|
||||
# Create backup script
|
||||
sudo vim /opt/multi-tenant-saas/scripts/backup-database.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR="/opt/multi-tenant-saas/backups"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/database_backup_$DATE.sql"
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Create database backup
|
||||
pg_dump -h localhost -U multi_tenant_prod_user -d multi_tenant_saas_prod -f $BACKUP_FILE
|
||||
|
||||
# Compress backup
|
||||
gzip $BACKUP_FILE
|
||||
|
||||
# Keep only last 30 days of backups
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||||
|
||||
echo "Database backup completed: $BACKUP_FILE.gz"
|
||||
```
|
||||
|
||||
### 2. Automated Backups
|
||||
```bash
|
||||
# Make backup script executable
|
||||
sudo chmod +x /opt/multi-tenant-saas/scripts/backup-database.sh
|
||||
|
||||
# Set up cron job for daily backups
|
||||
sudo crontab -e
|
||||
# Add: 0 2 * * * /opt/multi-tenant-saas/scripts/backup-database.sh
|
||||
```
|
||||
|
||||
## Security Hardening
|
||||
|
||||
### 1. Application Security
|
||||
```bash
|
||||
# Set proper file permissions
|
||||
sudo chown -R multi-tenant:multi-tenant /opt/multi-tenant-saas
|
||||
sudo chmod -R 750 /opt/multi-tenant-saas
|
||||
sudo chmod 600 /opt/multi-tenant-saas/.env
|
||||
|
||||
# Secure sensitive files
|
||||
sudo chmod 600 /etc/nginx/sites-available/multi-tenant-saas
|
||||
sudo chmod 600 /etc/systemd/system/gunicorn.service
|
||||
```
|
||||
|
||||
### 2. Database Security
|
||||
```bash
|
||||
# Configure PostgreSQL security
|
||||
sudo -u postgres psql
|
||||
|
||||
# Remove public access
|
||||
REVOKE ALL PRIVILEGES ON DATABASE multi_tenant_saas_prod FROM PUBLIC;
|
||||
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM PUBLIC;
|
||||
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM PUBLIC;
|
||||
REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
|
||||
|
||||
# Grant only to application user
|
||||
GRANT CONNECT ON DATABASE multi_tenant_saas_prod TO multi_tenant_prod_user;
|
||||
GRANT USAGE ON SCHEMA public TO multi_tenant_prod_user;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO multi_tenant_prod_user;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO multi_tenant_prod_user;
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Database Optimization
|
||||
```bash
|
||||
# Create database indexes
|
||||
sudo -u postgres psql -d multi_tenant_saas_prod
|
||||
|
||||
# Create indexes for common queries
|
||||
CREATE INDEX CONCURRENTLY idx_core_tenant_schema_name ON core_tenant(schema_name);
|
||||
CREATE INDEX CONCURRENTLY idx_core_user_username ON core_user(username);
|
||||
CREATE INDEX CONCURRENTLY idx_core_user_email ON core_user(email);
|
||||
CREATE INDEX CONCURRENTLY idx_core_user_tenant ON core_user(tenant_id);
|
||||
|
||||
# Analyze tables for better query planning
|
||||
ANALYZE;
|
||||
```
|
||||
|
||||
### 2. Application Optimization
|
||||
```bash
|
||||
# Configure Django settings for production
|
||||
sudo vim /opt/multi-tenant-saas/config/production.py
|
||||
```
|
||||
|
||||
```python
|
||||
# Production optimizations
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
|
||||
'LOCATION': 'redis://127.0.0.1:6379/1',
|
||||
'OPTIONS': {
|
||||
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Session configuration
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||
SESSION_CACHE_ALIAS = "default"
|
||||
|
||||
# Email configuration
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'smtp.your-email-provider.com'
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
|
||||
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
|
||||
```
|
||||
|
||||
## Testing and Verification
|
||||
|
||||
### 1. Health Checks
|
||||
```bash
|
||||
# Application health check
|
||||
curl -f https://your-domain.com/health/ || exit 1
|
||||
|
||||
# Database connectivity
|
||||
sudo -u multi-tenant psql -h localhost -d multi_tenant_saas_prod -c "SELECT 1;" || exit 1
|
||||
|
||||
# Redis connectivity
|
||||
redis-cli ping || exit 1
|
||||
```
|
||||
|
||||
### 2. Load Testing
|
||||
```bash
|
||||
# Install load testing tools
|
||||
pip install locust
|
||||
|
||||
# Create load test script
|
||||
sudo vim /opt/multi-tenant-saas/load-test.py
|
||||
```
|
||||
|
||||
```python
|
||||
from locust import HttpUser, task, between
|
||||
|
||||
class WebsiteUser(HttpUser):
|
||||
wait_time = between(1, 5)
|
||||
|
||||
def on_start(self):
|
||||
self.client.get("/api/v1/health/")
|
||||
|
||||
@task(3)
|
||||
def view_home(self):
|
||||
self.client.get("/")
|
||||
|
||||
@task(1)
|
||||
def api_call(self):
|
||||
self.client.get("/api/v1/core/tenants/")
|
||||
```
|
||||
|
||||
### 3. Security Testing
|
||||
```bash
|
||||
# Run security checks
|
||||
pip install bandit safety
|
||||
bandit -r /opt/multi-tenant-saas/backend/src/
|
||||
safety check
|
||||
|
||||
# SSL security test
|
||||
openssl s_client -connect your-domain.com:443 -servername your-domain.com | openssl x509 -noout -dates
|
||||
```
|
||||
|
||||
## Deployment Checklist
|
||||
|
||||
- [ ] System requirements met
|
||||
- [ ] Software dependencies installed
|
||||
- [ ] Database configured and secured
|
||||
- [ ] Application code deployed
|
||||
- [ ] Environment variables set
|
||||
- [ ] SSL certificate obtained
|
||||
- [ ] Nginx configured
|
||||
- [ ] Gunicorn service running
|
||||
- [ ] Payment gateways configured
|
||||
- [ ] Malaysian compliance settings
|
||||
- [ ] Security hardening completed
|
||||
- [ ] Monitoring and logging set up
|
||||
- [ ] Backup procedures implemented
|
||||
- [ ] Performance optimizations applied
|
||||
- [ ] Health checks passing
|
||||
- [ ] Load testing completed
|
||||
- [ ] Security testing completed
|
||||
|
||||
## Support and Maintenance
|
||||
|
||||
### Regular Maintenance
|
||||
- Daily: Check logs and monitor performance
|
||||
- Weekly: Review security updates and patches
|
||||
- Monthly: Database maintenance and optimization
|
||||
- Quarterly: Security audit and compliance review
|
||||
- Annually: Full system review and upgrade planning
|
||||
|
||||
### Emergency Procedures
|
||||
- Application failure: Check logs, restart services
|
||||
- Database issues: Restore from backup, contact support
|
||||
- Security incident: Follow incident response plan
|
||||
- Performance issues: Scale resources, optimize queries
|
||||
|
||||
### Support Contacts
|
||||
- Technical Support: support@yourplatform.com
|
||||
- Emergency Support: emergency@yourplatform.com
|
||||
- Security Issues: security@yourplatform.com
|
||||
- Sales Inquiries: sales@yourplatform.com
|
||||
Reference in New Issue
Block a user