version: "3.7"

volumes:
  node_modules:

networks:
  redis:
    driver: bridge
    ipam:
      config:
        - subnet: 10.0.0.0/16

services:
  # Single standalone instance. (NOT highly available, correct)
  redis-single-instance:
    image: redis:6

  # Multiple standalone instances. (highly availability, correct)
  redis-multi-instance-a:
    image: redis:6
  redis-multi-instance-b:
    image: redis:6
  redis-multi-instance-c:
    image: redis:6

  # Single cluster. (highly availability, potentially incorrect)
  redis-single-cluster-1:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.11
  redis-single-cluster-2:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.12
  redis-single-cluster-3:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.13
  redis-single-cluster-4:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.14
  redis-single-cluster-5:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.15
  redis-single-cluster-6:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.0.16
  redis-single-cluster:
    image: redis:6
    command: redis-cli -p 6379 --cluster create 10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 10.0.0.14:6379 10.0.0.14:6379 10.0.0.16:6379 --cluster-replicas 1 --cluster-yes
    depends_on:
      - redis-single-cluster-1
      - redis-single-cluster-2
      - redis-single-cluster-3
      - redis-single-cluster-4
      - redis-single-cluster-5
      - redis-single-cluster-6
    networks:
      redis:
        ipv4_address: 10.0.0.2

  # Multi cluster. (highly availability, correct, probably excessive)
  redis-multi-cluster-a-1:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.1.11
  redis-multi-cluster-a-2:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.1.12
  redis-multi-cluster-a-3:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.1.13
  redis-multi-cluster-a:
    image: redis:6
    command: redis-cli -p 6379 --cluster create 10.0.1.11:6379 10.0.1.12:6379 10.0.1.13:6379 --cluster-replicas 0 --cluster-yes
    depends_on:
      - redis-multi-cluster-a-1
      - redis-multi-cluster-a-2
      - redis-multi-cluster-a-3
    networks:
      redis:
        ipv4_address: 10.0.1.2

  redis-multi-cluster-b-1:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.2.11
  redis-multi-cluster-b-2:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.2.12
  redis-multi-cluster-b-3:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.2.13
  redis-multi-cluster-b:
    image: redis:6
    command: redis-cli -p 6379 --cluster create 10.0.2.11:6379 10.0.2.12:6379 10.0.2.13:6379 --cluster-replicas 0 --cluster-yes
    depends_on:
      - redis-multi-cluster-b-1
      - redis-multi-cluster-b-2
      - redis-multi-cluster-b-3
    networks:
      redis:
        ipv4_address: 10.0.2.2

  redis-multi-cluster-c-1:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.3.11
  redis-multi-cluster-c-2:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.3.12
  redis-multi-cluster-c-3:
    image: redis:6
    command: redis-server /etc/redis/redis.conf
    volumes:
      - type: bind
        source: ./.github/docker/cluster.redis.conf
        target: /etc/redis/redis.conf
    networks:
      redis:
        ipv4_address: 10.0.3.13
  redis-multi-cluster-c:
    image: redis:6
    command: redis-cli -p 6379 --cluster create 10.0.3.11:6379 10.0.3.12:6379 10.0.3.13:6379 --cluster-replicas 0 --cluster-yes
    depends_on:
      - redis-multi-cluster-c-1
      - redis-multi-cluster-c-2
      - redis-multi-cluster-c-3
    networks:
      redis:
        ipv4_address: 10.0.3.2

  # This container installs node modules into the node_modules volume.
  installer:
    image: "node:${NODE_VERSION}"
    working_dir: /workspace
    command: yarn install --immutable
    environment:
      NODE_ENV: development
      YARN_IGNORE_NODE: 1
    volumes:
      - type: bind
        source: .
        target: /workspace
      - type: volume
        source: node_modules
        target: /workspace/node_modules

  # This container watches for changes and builds the application.
  builder:
    depends_on:
      - installer
    image: "node:${NODE_VERSION}"
    working_dir: /workspace
    entrypoint: ./.github/docker/await.sh node_modules/.bin/tsc
    command: yarn build:development
    tty: true
    environment:
      NODE_ENV: development
      YARN_IGNORE_NODE: 1
    volumes:
      - type: bind
        source: .
        target: /workspace
      - type: volume
        source: node_modules
        target: /workspace/node_modules

  # This container runs the tests.
  runner:
    depends_on:
      - builder
      - redis-single-instance
      - redis-multi-instance-a
      - redis-multi-instance-b
      - redis-multi-instance-c
      - redis-single-cluster-1
      - redis-single-cluster-2
      - redis-single-cluster-3
      - redis-single-cluster-4
      - redis-single-cluster-5
      - redis-single-cluster-6
      - redis-single-cluster
      - redis-multi-cluster-a-1
      - redis-multi-cluster-a-2
      - redis-multi-cluster-a-3
      - redis-multi-cluster-a
      - redis-multi-cluster-b-1
      - redis-multi-cluster-b-2
      - redis-multi-cluster-b-3
      - redis-multi-cluster-b
      - redis-multi-cluster-c-1
      - redis-multi-cluster-c-2
      - redis-multi-cluster-c-3
      - redis-multi-cluster-c
    image: "node:${NODE_VERSION}"
    working_dir: /workspace
    entrypoint: ./.github/docker/await.sh node_modules/.bin/vitest ./.github/docker/await.sh build/index.js
    command: yarn test:development
    tty: true
    environment:
      NODE_ENV: development
    volumes:
      - type: bind
        source: .
        target: /workspace
      - type: volume
        source: node_modules
        target: /workspace/node_modules
    networks:
      default:
      redis:
        ipv4_address: 10.0.10.3
