rustis 0.24.0

Redis async driver for Rust
Documentation
# Redis version for the whole test suite, pinned on the minor so patch fixes
# still come in. A floating `alpine` tag drifts between CI runs and developer
# machines, and the same commit then passes on one and fails on the other.
# Override for a one-off run with `REDIS_VERSION=8.10-rc2-alpine ./docker_up.sh`;
# it does not belong in `.env`, which `set_host_ip.sh` rewrites on every start.

services:
# Standalone
  redis-standalone:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-standalone
    restart: always
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    # Absolute path: DEBUG RESTART and CRASH-AND-RECOVER re-execute argv[0] from
    # /data. --enable-module-command lets MODULE reach the server at all. The loop
    # restarts it with no Docker backoff, via the entrypoint that loads the modules.
    entrypoint:
      - /bin/sh
      - -c
      - 'trap "exit 0" TERM; while true; do /usr/local/bin/docker-entrypoint.sh "$$@" & wait $$!; done'
      - redis-restart-loop
    command: /usr/local/bin/redis-server --enable-debug-command yes --enable-module-command yes

# TLS
  redis-tls:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-tls
    restart: on-failure:20
    ports:
      - "6380:6380"
    volumes:
      - ./certs:/certs
    command: >
      redis-server --port 0 --tls-port 6380
      --tls-cert-file /certs/redis.crt
      --tls-key-file /certs/redis.key
      --tls-ca-cert-file /certs/ca.crt
      --tls-auth-clients no
      --requirepass pwd

# Sentinel
  redis-sentinel-master:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-sentinel-master
    ports: 
      - "6381:6381"
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "6381", "ping"]
      interval: 1s
    command: >
      redis-server --port 6381

  redis-sentinel-replica:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-sentinel-replica
    restart: on-failure:20
    ports:
      - "6382:6382"
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "6382", "ping"]
      interval: 1s
    command: >
      redis-server --port 6382 --replicaof "${HOST_IP}" 6381 --slave-announce-ip "${HOST_IP}"
    depends_on:
      redis-sentinel-master: { condition: service_healthy }

  redis-sentinel1:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-sentinel1
    restart: on-failure:20
    ports:
      - "26379:26379"
    depends_on:
      redis-sentinel-master: { condition: service_healthy }
    command: >
      sh -c "
      echo 'port 26379' > /tmp/sentinel.conf;
      echo 'sentinel monitor myservice ${HOST_IP} 6381 2' >> /tmp/sentinel.conf;
      echo 'sentinel announce-ip ${HOST_IP}' >> /tmp/sentinel.conf;
      echo 'sentinel announce-port 26379' >> /tmp/sentinel.conf;
      echo 'sentinel down-after-milliseconds myservice 1000' >> /tmp/sentinel.conf;
      echo 'sentinel failover-timeout myservice 1000' >> /tmp/sentinel.conf;
      redis-sentinel /tmp/sentinel.conf"

  redis-sentinel2:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-sentinel2
    restart: on-failure:20
    ports:
      - "26380:26380"
    links:
      - redis-sentinel-master:redis-sentinel-master
    depends_on:
      redis-sentinel-master: { condition: service_healthy }
    command: >
      sh -c "
      echo 'port 26380' > /tmp/sentinel.conf;
      echo 'sentinel monitor myservice ${HOST_IP} 6381 2' >> /tmp/sentinel.conf;
      echo 'sentinel announce-ip ${HOST_IP}' >> /tmp/sentinel.conf;
      echo 'sentinel announce-port 26380' >> /tmp/sentinel.conf;
      echo 'sentinel down-after-milliseconds myservice 1000' >> /tmp/sentinel.conf;
      echo 'sentinel failover-timeout myservice 1000' >> /tmp/sentinel.conf;
      redis-server /tmp/sentinel.conf --sentinel"

  redis-sentinel3:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-sentinel3
    restart: on-failure:20
    ports:
      - "26381:26381"
    links:
      - redis-sentinel-master:redis-sentinel-master
    depends_on:
      redis-sentinel-master: { condition: service_healthy }
    command: >
      sh -c "
      echo 'port 26381' > /tmp/sentinel.conf;
      echo 'sentinel monitor myservice ${HOST_IP} 6381 2' >> /tmp/sentinel.conf;
      echo 'sentinel announce-ip ${HOST_IP}' >> /tmp/sentinel.conf;
      echo 'sentinel announce-port 26381' >> /tmp/sentinel.conf;
      echo 'sentinel down-after-milliseconds myservice 1000' >> /tmp/sentinel.conf;
      echo 'sentinel failover-timeout myservice 1000' >> /tmp/sentinel.conf;
      redis-server /tmp/sentinel.conf --sentinel"

# Cluster
  cluster-init:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: cluster-init
    command: redis-cli --cluster create "${HOST_IP}":7000 "${HOST_IP}":7001 "${HOST_IP}":7002 "${HOST_IP}":7003 "${HOST_IP}":7004 "${HOST_IP}":7005 --cluster-replicas 1 --cluster-yes
    depends_on:
      redis-node1: { condition: service_healthy }
      redis-node2: { condition: service_healthy }
      redis-node3: { condition: service_healthy }
      redis-node4: { condition: service_healthy }
      redis-node5: { condition: service_healthy }
      redis-node6: { condition: service_healthy }

  redis-node1:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node1
    ports: ["7000:7000", "17000:17000"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7000", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7000 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7000 
      --cluster-announce-bus-port 17000 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

  redis-node2:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node2
    ports: ["7001:7001", "17001:17001"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7001", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7001 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7001 
      --cluster-announce-bus-port 17001 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

  redis-node3:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node3
    ports: ["7002:7002", "17002:17002"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7002", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7002 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7002 
      --cluster-announce-bus-port 17002 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

  redis-node4:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node4
    ports: ["7003:7003", "17003:17003"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7003", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7003 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7003 
      --cluster-announce-bus-port 17003 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

  redis-node5:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node5
    ports: ["7004:7004", "17004:17004"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7004", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7004 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7004 
      --cluster-announce-bus-port 17004 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

  redis-node6:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-node6
    ports: ["7005:7005", "17005:17005"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7005", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7005 --cluster-enabled yes 
      --cluster-config-file nodes.conf --cluster-node-timeout 5000 
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7005 
      --cluster-announce-bus-port 17005 --enable-debug-command yes --busy-reply-threshold 500 --appendonly yes

# Sacrificial cluster pair
#
# The topology mutators — ADDSLOTS, DELSLOTS, FORGET, MEET, REPLICATE, RESET,
# FAILOVER, FLUSHSLOTS, SET-CONFIG-EPOCH, MIGRATION IMPORT — were held to be
# untestable, which was true only of the *shared* cluster above: every other
# cluster test runs against it, so moving one of its slots breaks them all.
# It was never a property of the commands. These two nodes are cluster-enabled
# and deliberately left out of `cluster-init`, so they belong to no cluster and
# nothing else in the suite reads them. A test may reconfigure them freely, and
# the declared response type finally meets a real reply.
#
# Two rather than one: MEET, FORGET, REPLICATE and FAILOVER each need a second
# node to name.
  redis-spare-node1:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-spare-node1
    restart: on-failure:20
    ports: ["7006:7006", "17006:17006"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7006", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7006 --cluster-enabled yes
      --cluster-config-file nodes.conf --cluster-node-timeout 5000
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7006
      --cluster-announce-bus-port 17006 --enable-debug-command yes

  redis-spare-node2:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-spare-node2
    restart: on-failure:20
    ports: ["7007:7007", "17007:17007"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "7007", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 7007 --cluster-enabled yes
      --cluster-config-file nodes.conf --cluster-node-timeout 5000
      --cluster-announce-ip "${HOST_IP}" --cluster-announce-port 7007
      --cluster-announce-bus-port 17007 --enable-debug-command yes

# Sacrificial Sentinel
#
# Same reasoning for SENTINEL FAILOVER and SENTINEL SIMULATE-FAILURE: they take
# the monitored master down on purpose, which the Sentinel deployment above
# cannot survive without breaking every other sentinel test. This master and the
# single Sentinel watching it are monitored by nothing else.
  redis-spare-master:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-spare-master
    restart: on-failure:20
    ports: ["6383:6383"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "6383", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 6383

  redis-spare-replica:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-spare-replica
    restart: on-failure:20
    ports: ["6384:6384"]
    healthcheck:
      test: ["CMD", "redis-cli", "-p", "6384", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30
    command: >
      redis-server --port 6384 --replicaof "${HOST_IP}" 6383 --slave-announce-ip "${HOST_IP}"
    depends_on:
      redis-spare-master: { condition: service_healthy }

  redis-spare-sentinel:
    image: redis:${REDIS_VERSION:-8.8-alpine}
    container_name: redis-spare-sentinel
    # `always`, not a bounded `on-failure:N`: SENTINEL SIMULATE-FAILURE crashes
    # this process every time its test runs, so a finite budget is a number of
    # suite runs after which the container stays down and the test fails for a
    # reason that has nothing to do with the code.
    restart: always
    ports: ["26382:26382"]
    depends_on:
      redis-spare-master: { condition: service_healthy }
    # `quorum 1`: a lone Sentinel must be able to authorize the failover the
    # test asks it for.
    command: >
      sh -c "
      echo 'port 26382' > /tmp/sentinel.conf;
      echo 'sentinel monitor spareservice ${HOST_IP} 6383 1' >> /tmp/sentinel.conf;
      echo 'sentinel announce-ip ${HOST_IP}' >> /tmp/sentinel.conf;
      echo 'sentinel announce-port 26382' >> /tmp/sentinel.conf;
      echo 'sentinel down-after-milliseconds spareservice 1000' >> /tmp/sentinel.conf;
      echo 'sentinel failover-timeout spareservice 1000' >> /tmp/sentinel.conf;
      redis-sentinel /tmp/sentinel.conf"