version: '3.9'

services:
  redis_master:
    image: redis:7-alpine
    command:
      - redis-server
      - --maxmemory
      - 1gb
      - --maxmemory-policy
      - allkeys-lru
      - --appendonly
      - "yes"
      - --tcp-keepalive
      - "300"
      - --timeout
      - "300"
    volumes:
      - redis_data:/data
    networks:
      - database-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    deploy:
      resources:
        limits:
          memory: 1.2G
          cpus: '0.5'
        reservations:
          memory: 512M
          cpus: '0.1'
      placement:
        constraints:
          - "node.labels.role==db"
      replicas: 1

  redis_replica:
    image: redis:7-alpine
    command:
      - redis-server
      - --slaveof
      - redis_master
      - "6379"
      - --maxmemory
      - 512m
      - --maxmemory-policy
      - allkeys-lru
      - --appendonly
      - "yes"
      - --tcp-keepalive
      - "300"
    volumes:
      - redis_replica_data:/data
    networks:
      - database-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 45s
    deploy:
      resources:
        limits:
          memory: 768M
          cpus: '0.25'
        reservations:
          memory: 256M
          cpus: '0.05'
      placement:
        constraints:
          - "node.labels.role!=db"
      replicas: 2
    depends_on:
      - redis_master

  redis_sentinel:
    image: redis:7-alpine
    command:
      - redis-sentinel
      - /etc/redis/sentinel.conf
    configs:
      - source: redis_sentinel_config
        target: /etc/redis/sentinel.conf
    networks:
      - database-network
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "26379", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    deploy:
      resources:
        limits:
          memory: 128M
          cpus: '0.1'
        reservations:
          memory: 64M
          cpus: '0.05'
      replicas: 3
    depends_on:
      - redis_master

volumes:
  redis_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/redis/master
  redis_replica_data:
    driver: local

configs:
  redis_sentinel_config:
    content: |
      port 26379
      dir /tmp
      sentinel monitor mymaster redis_master 6379 2
      sentinel auth-pass mymaster yourpassword
      sentinel down-after-milliseconds mymaster 5000
      sentinel parallel-syncs mymaster 1
      sentinel failover-timeout mymaster 10000
      sentinel deny-scripts-reconfig yes

networks:
  database-network:
    external: true
