skip to Main Content

I’m trying to pass my redis password using docker-compose via environment variable but it gives me errors.

Here is part of mine docker-compose.yml with redis image:

  redis:
    image: redis
    container_name: redis
    # command: redis-server --requirepass mypassword <--- this works as expected
    # command: redis-server --requirepass ${REDIS_PASSWORD} <-- while this does not
    command: redis-server --requirepass $${REDIS_PASSWORD} <-- and this does not work either
    volumes:
      - redis:/var/lib/redis/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
    ports:
      - "6379"
    env_file:
      - .env.prod

My .env.prod:

REDIS_PASSWORD=mypassword

It gives me an error:

consumer: Cannot connect to redis://:**@redis:6379/0: WRONGPASS invalid username-password pair or user is disabled..

But if I specify password directly in docker-compose.yml without env variable, then it works.

7

Answers


  1. env_file allows to set environment variables in the container – while you need them in the environment of docker-compose in order to perform variable substitution for ${REDIS_PASSWORD}.

    To achieve your goal remove the env_file from your yml and, either:

    • rename your .env.prod file to just .env, so that docker-compose would automatically pick it; or,
    • specify it while calling docker-compose, by way of the --env-file parameter:
    docker-compose --env-file .env.prod up
    
    Login or Signup to reply.
  2. This should work:

        redis:
            image: redis
            command: >
              --requirepass ${REDIS_PASSWORD}
    
    Login or Signup to reply.
  3. None of the answers worked for me. Here is what I ended up doing, adjusted to
    the code snippet provided by OP:

    redis:
      image: redis
      container_name: redis
      command:
        - /bin/sh
        - -c
        # - Double dollars, so that the variable is not expanded by Docker Compose
        # - Surround by quotes, so that the shell does not split the password
        # - The ${variable:?message} syntax causes shell to exit with a non-zero
        #   code and print a message, when the variable is not set or empty
        - redis-server --requirepass "$${REDIS_PASSWORD:?REDIS_PASSWORD variable is not set}"
      volumes:
        - redis:/var/lib/redis/data
        - ./redis.conf:/usr/local/etc/redis/redis.conf
      ports:
        - "6379"
      env_file:
        - .env.prod
    

    I changed the command field, so that the command is run through the shell —
    this way, /bin/sh can expand the REDIS_PASSWORD variable or exit with an
    error message, if the variable could not be find.

    As for why the code snippet in question does not work:

    1. command: redis-server --requirepass ${REDIS_PASSWORD}

      In this case, the ${REDIS_PASSWORD} would be expanded by Docker Compose.
      Docker Compose first tries to find an environment variable called
      REDIS_PASSWORD. Then, Docker Compose looks for file .env (yes, even if
      the env_file field was provided). Because the variable is defined in file
      .env.prod, Compose cannot find it.

    2. command: redis-server --requirepass $${REDIS_PASSWORD}

      Here, ${REDIS_PASSWORD} is passed unexpanded to the redis-server command.
      This is because Docker runs the redis-server command directly, not
      through the shell. When one enters that command in a terminal emulator, the
      shell, usually Bash, expands the variable before running the command.

    Sources

    Login or Signup to reply.
  4. This works for me.
    Similar like Cezary Drożak answer, but less code.

    docker-compose.yml

      redis:
        image: redis:alpine
        restart: always
        command: /bin/sh -c "redis-server --requirepass $$REDIS_HOST_PASSWORD"
        env_file:
          - redis.env
    

    redis.env

    REDIS_HOST_PASSWORD=mypassword
    

    Source

    Login or Signup to reply.
  5. You need to set the Env vars and pass them like this:

    
      cache:
        image: redis:6.2-alpine
        restart: always
        environment:
          REDIS_PWD: '${REDIS_PWD}'
        ports:
          - '6379:6379'
        command: redis-server --save 20 1 --loglevel warning --requirepass $REDIS_PWD
        volumes:
          - cache:/data
    

    Than set it in your .env file:

    REDIS_PWD=ChangeMeLater!
    
    Login or Signup to reply.
    • redis-stack
    version: '3.8'
    
    services:
    
      redis:
        container_name: redis-stack
        image: 'redis/redis-stack:latest'
        restart: unless-stopped
        #command: ["redis-server", "/etc/redis/redis.conf"]
        environment:
          REDIS_ARGS: "--requirepass root"
        volumes:
          - ./redis-data:/data
          #- ./conf/users.acl:/etc/redis/users.acl:z
          #- ./conf/redis.conf:/etc/redis/redis.conf:z
        ports:
          - "6379:6379"#redis-server
          - "8001:8001" #RedisInsight
    
    Login or Signup to reply.
  6. if you’re trying to set the ACL user/pass instead of global –requiredpass, it can be done by creating de redis.conf file dinamically using the environment variables at the initialization command on a custom Dockerfile:

    
    FROM redis
    
    CMD echo "user $REDIS_USER ~* &* +@all on >$REDIS_PASSWORD" >/etc/redis/redis.conf & redis-server /etc/redis/redis.conf
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search