docker-compose redis password via environment variable
Asked Answered
P

8

53

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.

Perithecium answered 20/7, 2021 at 20:49 Comment(0)
B
27

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

Bamberger answered 12/6, 2022 at 14:25 Comment(1)
this worked for me. i tried the 1 & 2 mentioned as well but neither worked. needed to use the solution with /bin/sh & -c as well :)Coralloid
C
18

This should work:

    redis:
        image: redis
        command: >
          --requirepass ${REDIS_PASSWORD}
Cupbearer answered 8/10, 2021 at 15:35 Comment(3)
proper way as documented (hub.docker.com/r/bitnami/redis) is to provide an variable -> environment: - REDIS_PASSWORD=yourpass What you provided does not work, I'm getting exec: --: invalid optionWinwaloe
@Winwaloe pay attention to the fact that your link does not correspond to Redis official image on Docker hub. Your solution doesn't seem to work with the official image, but the answer of Cezary Drożak did the trick for meCantor
@Winwaloe your link refers to the bitnami versionRidglee
D
14

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

Deering answered 4/10, 2022 at 10:5 Comment(0)
P
4

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
Pl answered 22/7, 2021 at 9:5 Comment(0)
M
2
  • 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
Metameric answered 12/2, 2023 at 18:49 Comment(0)
L
2
Docker Secrets

Here's a snippet for those of you who believe in Docker secrets over environment variables. If you want to be goofy and put "unusual" characters in your password then make sure you add shell quoting around $(cat file). You could forgo the environment variable but using it makes the snippet more similar to what countless other Docker images provide out-of-the-box.

services:
  redis:
    image: redis:7-alpine
    environment:
      - REDIS_PASSWORD_FILE: /run/secrets/redis_password
    secrets:
      - redis_password
    command: sh -c "redis-server --requirepass $(cat $$REDIS_PASSWORD_FILE)"

secrets:
  redis_password:
    file: .secrets/redis-password.txt
Laudable answered 28/5, 2023 at 19:50 Comment(0)
D
1

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!
Diamagnetic answered 14/11, 2022 at 12:43 Comment(0)
S
0

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
Serna answered 25/4, 2023 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.