Search code examples
docker-composeredisredis-stack-server

Docker-Compose command for redis-stack-server persistence


If I use the default redis docker image configured with docker compose as such:

redis-storage:
  image: redis:7.0
  container_name: 'redis-storage'
  command: ["redis-server", "--save", "1200", "32", "--loglevel", "warning"]
  volumes:
    - redis-storage-data:/data

it starts up fine and writes to disk every 20 minutes if at least 32 changes.

But if I use the same command with image: redis/redis-stack-server:latest it appears to start okay, but it really goes into protected mode and becomes inaccessible. Commenting out the command, all works fine.

What is the correct command in docker-compose format that will allows altering the default save-to-disk parameters?

(Also tried alternative syntax: command: redis-server --save 1200 32)


Solution

  • Working solution for docker-compose schema '3.8':

    redis-stack-svc:
      image: redis/redis-stack-server:latest
      # use REDIS_ARGS for redis-stack-server instead of command arguments
      environment:
        - REDIS_ARGS=--save 1200 32
      volumes:
        - my-redis-data:/data
    

    Not easy to find a clear, non-conflicting example. And something of an historical bug.

    For redis-stack-server (when not using a local redis-stack.conf file mounted to the container) configuration for the underlying redis can be passed in via the REDIS_ARGS environment variable instead of directly to the command. (There are also environment vars for the stack modules, such as REDISJSON_ARGS, etc.

    However 'save' is particularly fussy. It expects two arguments (seconds, changes) but most configuration parameters expect one. Some forms of quoting the arguments would make it look like one argument, and the underlying argument parser would either be ignored or report 'wrong number of arguments' and put the server into protected mode.

    For save, you can also specify several conditionals. For example, the default is:

    save 3600 1 300 100 60 10000

    (Save after 1hr if 1 write, after 5min if 100 writes, after 60 sec if 10000 writes)

    For the original redis container, you can specify this in docker-compose as command line arguments using the following format:

    redis-storage:
      image: redis:7.0
      command: ["redis-server", "--save", "3600", "1", "300", "100", "60", "10000"]
      volumes:
        - my-redis-data:/data
    

    However, the underlying argument parsing logic creates a problem for redis-stack Both of these formats will be parsed incorrectly:

      # (valid syntax but ignored...'save' is actually set to 'nil')
      environment: 
        - REDIS_ARGS=--save 3600 1 300 100 60 10000
      
      # ('invalid number of arguments', server not started) 
      environment:
        - REDIS_ARGS="--save 3600 1 300 100 60 10000"  
    

    The correct syntax is obscure:

      # (using non-default values here to validate the behavior) 
      environment:
        - REDIS_ARGS=--save 3602 1 --save 302 100 --save 62 10000
    

    If you docker exec into the running container and invoke redis-cli CONFIG GET save it will return:

    root@f45860:/data# redis-cli CONFIG GET save
    1) "save"
    2) "3602 1 302 100 62 10000"
    
    

    There is also an alternative compose syntax example in the redis developer docs

      environment:
        - REDIS_ARGS:--save 20 1
    

    but compose schema 3.8 will complain (the example uses schema 3.9)