| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- services:
- # PostgreSQL Database
- postgres:
- image: postgres:15-alpine
- container_name: saas-postgres
- environment:
- POSTGRES_DB: ${POSTGRES_DB:-saas_db}
- POSTGRES_USER: ${POSTGRES_USER:-saas_user}
- POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password_change_me}
- POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256"
- volumes:
- - postgres_data:/var/lib/postgresql/data
- - ./database/init:/docker-entrypoint-initdb.d
- ports:
- - "5432:5432"
- networks:
- - saas-network
- restart: unless-stopped
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-saas_user} -d ${POSTGRES_DB:-saas_db}"]
- interval: 30s
- timeout: 10s
- retries: 3
- # Redis for caching and sessions
- redis:
- image: redis:7-alpine
- container_name: saas-redis
- command: redis-server --requirepass ${REDIS_PASSWORD:-redis_secure_password_change_me}
- ports:
- - "6379:6379"
- volumes:
- - redis_data:/data
- networks:
- - saas-network
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
- interval: 30s
- timeout: 10s
- retries: 3
- # PostgreSQL Admin Interface (pgAdmin)
- pgadmin:
- image: dpage/pgadmin4:latest
- container_name: saas-pgadmin
- environment:
- PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL:-admin@example.com}
- PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD:-admin_password_change_me}
- ports:
- - "5050:80"
- volumes:
- - pgadmin_data:/var/lib/pgadmin
- networks:
- - saas-network
- depends_on:
- - postgres
- restart: unless-stopped
- # API Gateway (Nginx)
- api-gateway:
- image: nginx:alpine
- container_name: saas-gateway
- ports:
- - "8888:80"
- - "8443:443"
- volumes:
- - ./nginx/nginx.conf:/etc/nginx/nginx.conf
- - ./nginx/conf.d:/etc/nginx/conf.d
- - ./ssl:/etc/nginx/ssl
- networks:
- - saas-network
- depends_on:
- - postgres
- - redis
- - auth-service
- restart: unless-stopped
- # Authentication Service
- auth-service:
- build:
- context: ./services/auth
- dockerfile: Dockerfile
- container_name: saas-auth
- environment:
- DATABASE_URL: postgresql://${POSTGRES_USER:-saas_user}:${POSTGRES_PASSWORD:-secure_password_change_me}@postgres:5432/${POSTGRES_DB:-saas_db}
- REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secure_password_change_me}@redis:6379
- JWT_SECRET: ${JWT_SECRET:-your_jwt_secret_change_me}
- NODE_ENV: development
- ports:
- - "3001:3001"
- volumes:
- - ./services/auth:/app
- - /app/node_modules
- networks:
- - saas-network
- depends_on:
- - postgres
- - redis
- restart: unless-stopped
- # API Service (Core API)
- api-service:
- build:
- context: ./services/api
- dockerfile: Dockerfile
- container_name: saas-api
- environment:
- DATABASE_URL: postgresql://${POSTGRES_USER:-saas_user}:${POSTGRES_PASSWORD:-secure_password_change_me}@postgres:5432/${POSTGRES_DB:-saas_db}
- REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secure_password_change_me}@redis:6379
- AUTH_SERVICE_URL: http://auth-service:3001
- NODE_ENV: development
- ports:
- - "3000:3000"
- volumes:
- - ./services/api:/app
- - /app/node_modules
- - ./apps:/apps
- networks:
- - saas-network
- depends_on:
- - postgres
- - redis
- - auth-service
- restart: unless-stopped
- # Storage Service (MinIO for S3-compatible storage)
- storage:
- image: minio/minio:latest
- container_name: saas-storage
- environment:
- MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin}
- MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin_change_me}
- ports:
- - "9000:9000"
- - "9001:9001"
- volumes:
- - minio_data:/data
- networks:
- - saas-network
- command: server /data --console-address ":9001"
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
- interval: 30s
- timeout: 20s
- retries: 3
- # Real-time Service (WebSocket support)
- realtime-service:
- build:
- context: ./services/realtime
- dockerfile: Dockerfile
- container_name: saas-realtime
- environment:
- REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secure_password_change_me}@redis:6379
- NODE_ENV: development
- ports:
- - "3002:3002"
- volumes:
- - ./services/realtime:/app
- - /app/node_modules
- networks:
- - saas-network
- depends_on:
- - redis
- restart: unless-stopped
- # Monitoring (Prometheus)
- prometheus:
- image: prom/prometheus:latest
- container_name: saas-prometheus
- ports:
- - "9090:9090"
- volumes:
- - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
- - prometheus_data:/prometheus
- networks:
- - saas-network
- restart: unless-stopped
- # Monitoring (Grafana)
- grafana:
- image: grafana/grafana:latest
- container_name: saas-grafana
- environment:
- GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin_password_change_me}
- ports:
- - "3003:3000"
- volumes:
- - grafana_data:/var/lib/grafana
- - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards
- - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources
- networks:
- - saas-network
- depends_on:
- - prometheus
- restart: unless-stopped
- # MCP Server
- mcp-server:
- build:
- context: ./mcp-server
- dockerfile: Dockerfile
- container_name: saas-mcp-server
- environment:
- SAAS_API_URL: http://api-gateway
- SAAS_AUTH_URL: http://auth-service/auth
- SAAS_STORAGE_URL: http://storage/storage
- DEBUG: "false"
- volumes:
- - ./mcp-server:/app
- - /app/node_modules
- networks:
- - saas-network
- depends_on:
- - api-gateway
- - auth-service
- - storage
- restart: unless-stopped
- profiles:
- - mcp
- volumes:
- postgres_data:
- redis_data:
- pgadmin_data:
- minio_data:
- prometheus_data:
- grafana_data:
- networks:
- saas-network:
- driver: bridge
|