services: # Load Balancer (NGINX) with WebSocket support and session persistence load-balancer: image: nginx:latest container_name: load-balancer ports: - "4000:80" # External port 4000 maps to NGINX's port 80 volumes: - ./nginx-websocket.conf:/etc/nginx/nginx.conf:ro # Mount NGINX configuration networks: - redis-cluster-net depends_on: - node-app-1 - node-app-2 - node-app-3 healthcheck: test: [ "CMD", "curl", "-f", "http://localhost/health" ] interval: 10s timeout: 5s retries: 5 # Node App Instance 1 node-app-1: build: context: . container_name: node-app-1 hostname: node-app-1 networks: - redis-cluster-net env_file: - .env.development depends_on: redis-node-1: condition: service_healthy redis-node-2: condition: service_healthy redis-node-3: condition: service_healthy localstack: condition: service_healthy ports: - "4001:4000" # Different external port for local access volumes: - .:/app - node-app-npm-cache:/app/node_modules # Node App Instance 2 node-app-2: build: context: . container_name: node-app-2 hostname: node-app-2 networks: - redis-cluster-net env_file: - .env.development depends_on: redis-node-1: condition: service_healthy redis-node-2: condition: service_healthy redis-node-3: condition: service_healthy localstack: condition: service_healthy ports: - "4002:4000" # Different external port for local access volumes: - .:/app - node-app-npm-cache:/app/node_modules # Node App Instance 3 node-app-3: build: context: . container_name: node-app-3 hostname: node-app-3 networks: - redis-cluster-net env_file: - .env.development depends_on: redis-node-1: condition: service_healthy redis-node-2: condition: service_healthy redis-node-3: condition: service_healthy localstack: condition: service_healthy ports: - "4003:4000" # Different external port for local access volumes: - .:/app - node-app-npm-cache:/app/node_modules # Redis Node 1 redis-node-1: build: context: ./redis container_name: redis-node-1 hostname: redis-node-1 restart: unless-stopped networks: - redis-cluster-net volumes: - redis-node-1-data:/data - redis-lock:/redis-lock healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 10 # Redis Node 2 redis-node-2: build: context: ./redis container_name: redis-node-2 hostname: redis-node-2 restart: unless-stopped networks: - redis-cluster-net volumes: - redis-node-2-data:/data - redis-lock:/redis-lock healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 10 # Redis Node 3 redis-node-3: build: context: ./redis container_name: redis-node-3 hostname: redis-node-3 restart: unless-stopped networks: - redis-cluster-net volumes: - redis-node-3-data:/data - redis-lock:/redis-lock healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 10 # LocalStack localstack: image: localstack/localstack:4.13.1 container_name: localstack hostname: localstack networks: - redis-cluster-net restart: unless-stopped volumes: - ./certs:/tmp/certs:ro # only if your script reads /tmp/certs/... - ./localstack/init:/etc/localstack/init/ready.d:ro - /var/run/docker.sock:/var/run/docker.sock env_file: - .env.localstack.docker ports: - "4566:4566" healthcheck: test: [ "CMD", "curl", "-f", "http://localhost:4566/_localstack/health" ] interval: 10s timeout: 5s retries: 5 start_period: 20s networks: redis-cluster-net: driver: bridge volumes: node-app-npm-cache: redis-node-1-data: redis-node-2-data: redis-node-3-data: redis-lock: