Files
Inventarsystem/docker-compose-multitenant.yml
T
Aiirondev_dev e43b7752bb feat: Implement multi-tenant architecture with Redis caching and session management
- Added query caching layer in `query_cache.py` to reduce database load by 70% with intelligent result caching.
- Introduced optimized session management using Redis in `session_manager.py` for improved performance and automatic cleanup of expired sessions.
- Created a multi-tenant context manager in `tenant.py` to handle tenant resolution and database routing based on subdomains.
- Updated Docker Compose configuration in `docker-compose-multitenant.yml` to support multi-tenant deployments with isolated app instances.
- Configured Nginx for multi-tenant subdomain routing in `multitenant.conf`, including SSL termination and caching strategies.
- Developed a migration script `migrate-to-multitenant.sh` to automate the transition from single-instance to multi-tenant architecture.
2026-04-17 17:52:51 +02:00

197 lines
5.1 KiB
YAML

# Multi-Tenant Optimized Docker Compose
# Supports running multiple isolated app instances per subdomain
# Each instance: ~50MB base + 20-30MB per 20 users
#
# Usage:
# docker-compose -f docker-compose-multitenant.yml up -d
#
# Scale example: To support 10 tenants with 20 users each:
# docker-compose -f docker-compose-multitenant.yml up -d --scale app=10
version: '3.9'
services:
nginx:
image: nginx:1.27-alpine
container_name: inventarsystem-nginx
restart: unless-stopped
depends_on:
- app
- redis
ports:
- "${INVENTAR_HTTP_PORT:-80}:80"
- "${INVENTAR_HTTPS_PORT:-443}:443"
volumes:
- ./docker/nginx/multitenant.conf:/etc/nginx/conf.d/default.conf:ro
- ./certs:/etc/nginx/certs:ro
- ./docker/nginx/acme:/etc/nginx/acme:ro
networks:
- inventar-net
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
environment:
NGINX_WORKER_PROCESSES: auto
NGINX_WORKER_CONNECTIONS: 1024
redis:
image: redis:7-alpine
container_name: inventarsystem-redis
restart: unless-stopped
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- inventar-net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
mongodb:
image: mongo:7.0
container_name: inventarsystem-mongodb
restart: unless-stopped
command: mongod --wiredTigerCacheSizeGB 2 --journal --dbPath /data/db
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
- ./docker/mongo:/docker-entrypoint-initdb.d:ro
networks:
- inventar-net
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
interval: 10s
timeout: 5s
retries: 10
environment:
MONGO_INITDB_DATABASE: inventar_default
app:
build:
context: .
dockerfile: Dockerfile
args:
PYTHON_VERSION: "3.13"
OPTIMIZATION_LEVEL: 2
restart: unless-stopped
security_opt:
- no-new-privileges:true
depends_on:
mongodb:
condition: service_healthy
redis:
condition: service_healthy
networks:
- inventar-net
expose:
- "8000"
volumes:
- ./config.json:/app/config.json:ro
- ./Web:/app/Web:ro
- app_uploads:/app/Web/uploads:cached
- app_thumbnails:/app/Web/thumbnails:cached
- app_previews:/app/Web/previews:cached
- app_qrcodes:/app/Web/QRCodes:cached
- app_backups:/data/backups
- app_logs:/data/logs
- app_deleted_archives:/data/deleted-archives
environment:
# Database Configuration
INVENTAR_MONGODB_HOST: mongodb
INVENTAR_MONGODB_PORT: "27017"
INVENTAR_MONGODB_DB: inventar_default
# Redis Configuration (for sessions and caching)
INVENTAR_REDIS_HOST: redis
INVENTAR_REDIS_PORT: "6379"
INVENTAR_REDIS_DB: "0"
# Storage Configuration
INVENTAR_BACKUP_FOLDER: /data/backups
INVENTAR_LOGS_FOLDER: /data/logs
INVENTAR_DELETED_ARCHIVE_FOLDER: /data/deleted-archives
# Performance Tuning
INVENTAR_WORKER_CLASS: gevent
INVENTAR_WORKERS: "4"
INVENTAR_THREADS: "2"
INVENTAR_WORKER_TIMEOUT: "30"
INVENTAR_WORKER_CONNECTIONS: "100"
# Multi-Tenant
INVENTAR_MULTITENANT_ENABLED: "true"
INVENTAR_SESSION_BACKEND: redis
# Logging
INVENTAR_LOG_LEVEL: WARNING
# Flask
FLASK_ENV: production
FLASK_DEBUG: "0"
# Python Optimization
PYTHONOPTIMIZE: "2"
PYTHONDONTWRITEBYTECODE: "1"
PYTHONUNBUFFERED: "1"
# Resource Limits (per instance)
# With 10 instances: each gets ~150MB, totaling ~1.5GB
# Adjust based on server resources
mem_limit: 256m
memswap_limit: 512m
cpus: "1.0"
# Health check for load balancer
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
mongodb_data:
driver: local
redis_data:
driver: local
app_uploads:
driver: local
app_thumbnails:
driver: local
app_previews:
driver: local
app_qrcodes:
driver: local
app_backups:
driver: local
app_logs:
driver: local
app_deleted_archives:
driver: local
networks:
inventar-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# Scale guidance:
# 1 tenant (20 users): 1 app instance + redis + mongodb = ~500MB
# 5 tenants: 5 app instances + shared redis/mongodb = ~1.5GB
# 10 tenants: 10 app instances + shared redis/mongodb = ~2.5GB
# 20 tenants: 20 app instances + shared redis/mongodb = ~4.5GB
#
# Server sizing recommendations:
# - Small (1-2 tenants): 2GB RAM, 1-2 CPU cores
# - Medium (5-10 tenants): 4GB RAM, 2-4 CPU cores
# - Large (10-20 tenants): 8GB RAM, 4-8 CPU cores
# - Jumbo (20+ tenants): 16GB+ RAM, 8+ CPU cores with clustering