37

Currently I have the below service configured in my docker-compose which works correct with redis password. However, I would like to use also redis username together with password. Is there any similar command to requirepass or something else to enable username?

version: '3.9'
volumes:
  redis_data: {}
networks:
  ee-net:
    driver: bridge
services:
  redis:
    image: 'redis:latest'
    container_name: redis
    hostname: redis
    networks:
      - ee-net
    ports:
      - '6379:6379'
    command: '--requirepass redisPassword'
    volumes:
      - redis_data:/data

8 Answers 8

26

You can specify a config file

$ cat redis.conf
requirepass password
#aclfile /etc/redis/users.acl

Then add the following to your docker compose file

version: '3'
services:
  redis:
    image: redis:latest
    command: ["redis-server", "/etc/redis/redis.conf"]
    volumes:
      - ./redis.conf:/etc/redis/redis.conf
    ports:
      - "6379:6379"

Then you will get the password requirements

redis-cli
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH password
OK
127.0.0.1:6379> ping
PONG

You may want to look into the ACLs line commented out there if you require more fine grained control

Sign up to request clarification or add additional context in comments.

Comments

16

Passing the users as environment flags was enough for me. However, this seems to only work with the redis/redis-stack docker image:

  redis:
    image: redis/redis-stack:6.2.6-v7
    restart: always
    environment:
      REDIS_ARGS: "--requirepass mypassword --user username on > mypassword ~* allcommands --user default off nopass nocommands"
    ports:
      - "8001:8001"
      - "6379:6379"
    volumes:
      - ./data/redis:/data

This disables the "default" redis user and activates user called "username" with a password of "password". the ACL syntax is well covered by Redis docs.

The sample above also works with redis-stack-server image. The idea is to take advantage of this section in the Redis config documentation:

The format of the arguments passed via the command line is exactly the same as the one used in the redis.conf file, with the exception that the keyword is prefixed with --.

1 Comment

This only works with redis/redis-stack. Does not work with redis/latest image. Also your example is not clear as you example password is "password". Note the >password is the literal password. so if your password is mypassword you need to adjust it to >mypassword
10

None of these answers seemed to answer the question directly, which is how to create a custom username and a custom password with the redis:latest container image with docker-compose. (Not just applying a custom password for the default user)

First of all, there isn't an easily supported way to do this with the redis:latest image. You can accomplish this directly with redis-stack images, but that is not what op requested. Not to say its impossible, but the way redis handles permissions with its access control lists requires you to create a user and grant permissions with their acl files in a script.

I was able to accomplish creating a custom user, assign them a password, and permissions with docker-compose + Dockerfile + a custom-entrypoint.sh. I also added the ability to disable the default user as well. These are the steps:

  1. Directory structure
.
├── docker-compose.yaml
├── .env
│   └── .env.dev.msg-broker.reddis
└──  services
    └──  msg-broker
        ├── custom-entrypoint.sh
        └── Dockerfile.dev
  1. Configure your docker-compose.yaml
version: '3.3'
services:
  msg-broker:
    container_name: "msg-broker"
    build:
      context: ./services/msg-broker
      dockerfile: Dockerfile.dev
    env_file:
      - ./.env/.env.dev.msg-broker.reddis
    ports:
      - "6379:6379"
  1. Configure the env var file. You can also accomplish this by applying the variables directly in the docker-compose.yaml by creating an environment key instead. This is where you can configure you username and password, and if you want to keep the default user or not.
REDIS_USERNAME=myadmin
REDIS_PASSWORD=MyAdm1nP455w0rd
REDIS_DISABLE_DEFAULT_USER="true"
  1. Configure Dockerfile, notice how the custom-entrypoint.sh is copied over and ran instead of the default one directly.
FROM redis:latest

# Copy the custom entrypoint script
COPY custom-entrypoint.sh /usr/local/bin/custom-entrypoint.sh
RUN chmod +x /usr/local/bin/custom-entrypoint.sh

ENTRYPOINT ["custom-entrypoint.sh"]
  1. Configure the custom-entrypoint.sh. This is where the real configuration happens.
#!/bin/sh

# Set up Redis configuration directory
mkdir -p /usr/local/etc/redis

# Dynamically generate Redis configuration and ACL files here, using environment variables
echo "aclfile /usr/local/etc/redis/custom_aclfile.acl" > /usr/local/etc/redis/redis.conf

# Generate ACL file using environment variables
if [ -n ${REDIS_USERNAME} ] && [ -n ${REDIS_PASSWORD} ]; then
    echo "user ${REDIS_USERNAME} on allkeys allchannels allcommands >${REDIS_PASSWORD} " > /usr/local/etc/redis/custom_aclfile.acl
fi

# Disable default user
if [ $(echo ${REDIS_DISABLE_DEFAULT_USER}) == "true" ]; then
    echo "user default off nopass nocommands" >> /usr/local/etc/redis/custom_aclfile.acl
fi

# Call the original Docker entrypoint script with redis-server and the path to the custom Redis configuration
exec docker-entrypoint.sh redis-server /usr/local/etc/redis/redis.conf
  1. Run it
docker-compose up --build

You should be able to adjust the permissions for your users needs by tweaking the echo "user ${REDIS_USERNAME} on allkeys allchannels allcommands >${REDIS_PASSWORD} " > /usr/local/etc/redis/custom_aclfile.acl command in the custom-entrypoint script. I know the permissions I assigned give my user god like control, however I needed this for my celery instance to work, see this post for more info.

Comments

3

You're missing redis-server in your command. Please try the following command instead:

redis-server --requirepass redisPassword

In case you want to run your Redis server with a configuration file, use this command:

command: redis-server /path/to/redis.conf
volumes:
    - /local/path/to/redis.conf:/path/to/redis.conf

To define a password in your configuration file, use requirepass as shown below:

requirepass redisPassword

References

Comments

3

While trying to look for an answer to a similar question I stumbled across this thread, so here's what I found after digging a bit more. Disclosure, I'm using the bitnami/redis Docker Image for my Redis requirements.

Redis provides a default user and it is possible to add a password to this particular user. For the Bitnami Image, it is possible to add a password for authentication by passing the REDIS_PASSWORD=password environment variable.

screenshot from the Redis ACL docs

Thereafter all clients can authenticate as the default user by connecting through the URL;

redis://default:password@ip-address:6379

Now of course, using default authentication credentials does not sound like a good idea which is why it is recommended you go through the detailed Redis Access Control List (Redis ACL) documentation for more information on the same.

With a proper ACL practice in place, the Redis URL would look something like:

redis://naruto:[email protected]:2451

...where naruto is a "user" with proper ACL permissions in place and kageno-bunshin-jutsu is the password for the user. The 172.133.129.1 is the IP address of the node where the Redis instance is accessible and 2451 is the port number.

Comments

1

I had been using Redis via docker with the command

docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:lates

I could spin up a password-protected redis-stack-server docker instance via the command

docker run -d --name redis-stack-server -p 6379:6379 -e REDIS_ARGS="--requirepass <password>" redis/redis-stack-server:latest

you can login into this instance via RedisInsight or any other client using and user name "default" which is the default username in redis

1 Comment

OP is using image redis:latest not redis-stack-server, they are different. redis-stack-server has other mechanisms built into the image that allow you to do what you did. redis:latest does not.
1

enter image description here

An alternate approach to using a Redis configuration file (redis.conf), you can do so by including the necessary configuration directly in the command. The command option sets up the custom user with the provided username, password, and permissions, and disables the default user.Define environment variables REDIS_USERNAME, REDIS_PASSWORD, and REDIS_PERMISSION.

2 Comments

Love the screenshot but maybe you can add a properly formatted code block?
Love the Love the screenshot part of your comment 👌😂
1

It took me some time to figure this one out.

First of all:
.env file is for docker compose
env_file: "./docker.env" is for in the container.

my compose looks like this:

redis:
    image: bitnami/redis:latest
    env_file: "./docker.env"

    restart: unless-stopped
    container_name: docker.redis
    tty: true
    ports:
      - "6379:6379"
    networks:
      - docker.network
    volumes:
      - ./docker/redis:/bitnami/redis/data

    command: /bin/sh -c "redis-server --requirepass $$REDIS_ROOT_PASSWORD"

    environment:
      ALLOW_EMPTY_PASSWORD: ${REDIS_ALLOW_EMPTY_PASSWORD:-no}

And I don't use a .env so in my case the ALLOW_EMPTY_PASSWORD will be no as assigned from the docker compose file. Any extra REDIS_ROOT_PASSWORD environment variable would be overwritten because I have no .env file.

For IN the container the ./docker.env file holds the REDIS_ROOT_PASSWORD

# REDIS
REDIS_HOST=docker.redis
REDIS_PORT=6379
REDIS_ROOT_PASSWORD="aYVX7EwVmmxKPCDmwMtyKVge8oLd2t82"

these are settings available IN the container. And thats's where the password gets set.

command: /bin/sh -c "redis-server --requirepass $$REDIS_ROOT_PASSWORD"

Dubble $$ so the variable is used in the container and not during the composing.

Not your question but maybe handy for trespassers...

My php (8.3) then reads the .env and uses that data to create the connection.

    public function __construct()
    {
        include_once 'Dot.php';
        $env = Dot::handle();

        if (!$env->redisHost) {
            echo "missing redisHost in env\n";
            exit;
        }

        $this->redis = new Redis();
        $this->redis->connect($env->redisHost, $env->redisPort);
        $this->redis->rawCommand('auth', 'default', $env->redisRootPassword);
    } 

    public function test()
    {
        $this->redis->setex('hello', 60, 'Hello World');
        echo $this->redis->get('hello');
    }

Hmm... I didn't set the username...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.