# Falah OS v1.3 - High Availability Infrastructure # Usage: docker-compose -f docker-compose.yml -f docker-compose.ha.yml up -d version: '3.8' services: # ============================================================================= # HIGH AVAILABILITY DATABASE # ============================================================================= postgres-primary: image: postgres:16-alpine container_name: falah-postgres-primary environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=falahsecure - POSTGRES_DB=falahdb - POSTGRES_HOST_AUTH_METHOD=trust volumes: - postgres-primary-data:/var/lib/postgresql/data - ./infrastructure/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql networks: - falah-network deploy: resources: limits: cpus: '2.0' memory: 4G reservations: cpus: '1.0' memory: 2G command: > postgres -c max_connections=300 -c shared_buffers=2GB -c effective_cache_size=6GB -c maintenance_work_mem=512MB -c checkpoint_completion_target=0.9 -c wal_level=replica -c max_wal_senders=10 -c wal_keep_size=1GB -c hot_standby=on postgres-replica-1: image: postgres:16-alpine container_name: falah-postgres-replica-1 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=falahsecure - POSTGRES_DB=falahdb volumes: - postgres-replica-1-data:/var/lib/postgresql/data networks: - falah-network depends_on: - postgres-primary deploy: resources: limits: cpus: '2.0' memory: 4G command: > postgres -c hot_standby=on -c hot_standby_feedback=on -c max_standby_streaming_delay=30s postgres-replica-2: image: postgres:16-alpine container_name: falah-postgres-replica-2 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=falahsecure - POSTGRES_DB=falahdb volumes: - postgres-replica-2-data:/var/lib/postgresql/data networks: - falah-network depends_on: - postgres-primary deploy: resources: limits: cpus: '2.0' memory: 4G command: > postgres -c hot_standby=on -c hot_standby_feedback=on -c max_standby_streaming_delay=30s # ============================================================================= # REDIS HIGH AVAILABILITY (Sentinel) # ============================================================================= redis-master: image: redis:7-alpine container_name: falah-redis-master command: > redis-server --appendonly yes --maxmemory 2gb --maxmemory-policy allkeys-lru --requirepass falahsecure volumes: - redis-master-data:/data networks: - falah-network deploy: resources: limits: cpus: '1.0' memory: 2G redis-replica-1: image: redis:7-alpine container_name: falah-redis-replica-1 command: > redis-server --appendonly yes --replicaof falah-redis-master 6379 --masterauth falahsecure --requirepass falahsecure volumes: - redis-replica-1-data:/data networks: - falah-network depends_on: - redis-master deploy: resources: limits: cpus: '1.0' memory: 2G redis-replica-2: image: redis:7-alpine container_name: falah-redis-replica-2 command: > redis-server --appendonly yes --replicaof falah-redis-master 6379 --masterauth falahsecure --requirepass falahsecure volumes: - redis-replica-2-data:/data networks: - falah-network depends_on: - redis-master deploy: resources: limits: cpus: '1.0' memory: 2G redis-sentinel: image: redis:7-alpine container_name: falah-redis-sentinel command: > redis-sentinel --sentinel monitor falah-master falah-redis-master 6379 2 --sentinel down-after-milliseconds falah-master 5000 --sentinel failover-timeout falah-master 60000 --sentinel parallel-syncs falah-master 1 volumes: - ./infrastructure/redis/sentinel.conf:/etc/redis/sentinel.conf networks: - falah-network depends_on: - redis-master - redis-replica-1 - redis-replica-2 # ============================================================================= # CONNECTION POOLING # ============================================================================= pgbouncer: image: pgbouncer/pgbouncer:latest container_name: falah-pgbouncer environment: - DATABASE_URL=postgresql://postgres:falahsecure@falah-postgres-primary:5432/falahdb - POOL_MODE=transaction - MAX_CLIENT_conn=500 - DEFAULT_POOL_SIZE=50 - MIN_POOL_SIZE=10 volumes: - ./infrastructure/pgbouncer/pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini - ./infrastructure/pgbouncer/userlist.txt:/etc/pgbouncer/userlist.txt ports: - "6432:5432" networks: - falah-network depends_on: - postgres-primary # ============================================================================= # LOAD BALANCER (Traefik) # ============================================================================= traefik: image: traefik:v3.0 container_name: falah-traefik command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.email=admin@falah-os.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" - "--log.level=INFO" - "--accesslog=true" ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./infrastructure/traefik/traefik.yml:/etc/traefik/traefik.yml:ro - ./infrastructure/traefik/acme.json:/letsencrypt/acme.json networks: - falah-network restart: unless-stopped # ============================================================================= # OBSERVABILITY STACK # ============================================================================= prometheus: image: prom/prometheus:latest container_name: falah-prometheus volumes: - ./infrastructure/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' ports: - "9090:9090" networks: - falah-network restart: unless-stopped grafana: image: grafana/grafana:latest container_name: falah-grafana environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-changeme} - GF_INSTALL_PLUGINS=grafana-piechart-panel volumes: - grafana-data:/var/lib/grafana - ./infrastructure/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./infrastructure/grafana/datasources:/etc/grafana/provisioning/datasources:ro ports: - "3000:3000" networks: - falah-network depends_on: - prometheus restart: unless-stopped loki: image: grafana/loki:latest container_name: falah-loki volumes: - ./infrastructure/loki/loki-config.yml:/etc/loki/local-config.yaml:ro - loki-data:/loki ports: - "3100:3100" networks: - falah-network restart: unless-stopped promtail: image: grafana/promtail:latest container_name: falah-promtail volumes: - ./infrastructure/promtail/promtail-config.yml:/etc/promtail/config.yml:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro command: - "-config.file=/etc/promtail/config.yml" networks: - falah-network restart: unless-stopped alertmanager: image: prom/alertmanager:latest container_name: falah-alertmanager volumes: - ./infrastructure/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro - alertmanager-data:/alertmanager ports: - "9093:9093" networks: - falah-network restart: unless-stopped volumes: postgres-primary-data: driver: local postgres-replica-1-data: driver: local postgres-replica-2-data: driver: local redis-master-data: driver: local redis-replica-1-data: driver: local redis-replica-2-data: driver: local prometheus-data: driver: local grafana-data: driver: local loki-data: driver: local alertmanager-data: driver: local networks: falah-network: driver: bridge ipam: config: - subnet: 172.28.0.0/16