Learn how to remove the Redis warning overcommit_memory is set to 0, background save may fail under low memory conditions in your Redis Container.

How to remove Redis warning on Docker: Memory overcommit must be enabled

Redis is pretty famous nowadays, it can be used as a database, a cache system, or even a message broker. I would end up repeating myself trying to list all the possible use cases of Redis in projects out there, so let's keep it simple, Redis is used everywhere in production projects and therefore, it's pretty usual to have a local instance for development purposes.

After trying to implement a new Redis container to help me out with a Django project, I used a pretty basic configuration to start a container with Redis 7.2. It worked out of the box with the following configuration:

version: '3.8'
services:
    cache:
        image: redis:7.2-alpine
        restart: always
        ports:
            - 6379:6379
        command: redis-server --save 20 1 --loglevel warning
        volumes:
            - ./data/redis:/data

Yet I was surprised that there was a warning mentioning something critical (at least not for the moment for me): warning overcommit_memory is set to 0! Background save may fail under low memory conditions. Being disabled can also cause failures without low memory conditions.

The same warning provides a way to remove it, but in order to remove this warning properly in Docker, you will need to follow some extra steps as a default image won't be enough. In this tutorial, I will explain to you how to easily solve this warning in your Redis server containerized on Docker.

1. Create an initialization script

We need to tweak the kernel's memory overcommit handling in the container. When the vm.overcommit_memory option is set to 1, the kernel will always allow memory allocation even if it doesn't have enough memory to cover the allocation. This setting is especially useful for applications that rely on being able to allocate more memory than is physically available (which is usually the case for most of the applications that use Redis).

In the case of our docker container, we can run a .sh file to tweak this setting and start the Redis server as usual. Create the init.sh script for Redis with the following content in your project:

# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.
# To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot
# or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
# The overcommit_memory has 3 options.
# 0, the system kernel check if there is enough memory to be allocated to the process or not, 
# if not enough, it will return errors to the process.
# 1, the system kernel is allowed to allocate the whole memory to the process
# no matter what the status of memory is.
# 2, the system kernel is allowed to allocate a memory whose size could be bigger than
# the sum of the size of physical memory and the size of exchange workspace to the process.
sysctl vm.overcommit_memory=1

# Start redis server
redis-server /usr/local/etc/redis/redis.conf --loglevel warning --bind 0.0.0.0

Save the changes and continue with the next step.

2. Create a Redis configuration file

You need to have a configuration file with all the settings of Redis that you need. If you don't have any, you can visit the official Redis website here to get an example of the configuration file for each version. In my case, I'm going to use the default configuration file for Redis 7.2 from the official website and I'm going to store it in the redis.conf and it will be stored in the root directory of my project.

3. Create a Dockerfile for the Redis container

Instead of using a ready-to-use container of Redis, we need to start from the base image of Redis, in my case version 7.2, and will run some extra commands to copy the previously created redis.conf and init.sh files in the container and will allow the sh script to be executable:

FROM redis:7.2-alpine

WORKDIR /redis

COPY redis.conf /usr/local/etc/redis/redis.conf

COPY init.sh ./

RUN chmod +x init.sh

Save the changes to the file and continue with the next step.

4. Configure docker-compose.yml with the new custom Redis container

The last thing we need to do is to adjust our container to be built using the Dockerfile we created and to start with a different entry point, which is going to be the init.sh script. There is something important to note in this configuration besides the initialization script, and that's the privileged option that is set to true. This option is often used when a container needs to perform tasks that require elevated privileges, such as accessing devices or interacting with the kernel in ways that are not allowed by default, which is exactly what we need to adjust the overcommit_memory option.

The docker-compose.yml file with the Redis container will look similar to this:

version: '3.8'
services:
    cache:
        # Adjust the build context to your needs targetting the created Dockerfile
        build:
            context: ./dockerfiles/redis
            dockerfile: Dockerfile
        image: redis:7.2-alpine
        restart: always
        ports:
            - 6379:6379
        # Run the init script
        command: sh -c "./init.sh"
        # Run as privileged to allow the container to change the vm.overcommit_memory setting
        privileged: true
        volumes:
            - ./docker/data/redis:/data

After adjusting the docker-compose.yml file, restart, and rebuild your container:

docker compose up --build -d

And you should see now that the container doesn't have this warning anymore:

Happy coding ❤️!


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors