The Redis Docker Official Image includes both the Redis server and the Redis CLI. We discuss the setup process to use both on Windows 10 Pro and Ubuntu 22.10 kinetic. The actual Redis database file resides in a directory of our own designation on the host machine. We test the setup using the container CLI, as well as a very simple Rust program and a simple Python script.

092-feature-image.png
Using the Redis Official Docker Image on Windows 10 and Ubuntu 22.10 kinetic.

Table of contents

Get It Ready in 5 (Five) Steps

❶ Pull the latest Redis Docker Official Image.

▶️Windows 10: docker pull redis
▶️Ubuntu 22.10: $ sudo docker pull redis

❷ Create a bridge network to enable running Redis CLI.

▶️Windows 10: docker network create -d bridge redis-network
▶️Ubuntu 22.10: $ sudo docker network create -d bridge redis-network

❸ Prepare database directory, i.e. data volume.

On Windows 10, the database directory is D:\Database\Redis, which translates to //d/database/redis for volume mounting. On Ubuntu 22.10, the database directory is /home/behai/Public/database/redis.

The data volume mountings are then:

▶️Windows 10: --mount type=bind,source=//d/database/redis,target=/data
▶️Ubuntu 22.10: --mount type=bind,source=/home/behai/Public/database/redis,target=/data

❹ 🚀 The final command is:

▶️Windows 10: docker run --publish=6379:6379 --network redis-network -d -it --mount type=bind,source=//d/database/redis,target=/data --name redis-docker redis
▶️Ubuntu 22.10: $ sudo docker run --publish=6379:6379 --network redis-network -d -it --mount type=bind,source=/home/behai/Public/database/redis,target=/data --name redis-docker redis 

❺ Verify the container is running.

▶️Windows 10: docker logs redis-docker
▶️Ubuntu 22.10: $ sudo docker logs redis-docker

The output should look like:

092-01.png

The following warning line should not be in the above output:

# Warning: Could not create server TCP listening socket ::1:16379: bind: Cannot assign requested address

The Redis container should now be ready. We can now talk to the Redis server using Redis CLI. And also programmatically via Rust and Python.

After Pulling, Storing and Loading the Image Locally

After pulling any image, we can save it locally and later load it from another machine etc., which helps saving some bandwidth data 😂…

I pull the Redis image on my Windows 10 machine using the command:

F:\>docker pull redis

We can then verify it’s been pulled successfully, and also to find out the image TAG label, with:

F:\>docker images

We should find it in the output list:

REPOSITORY          TAG                       IMAGE ID       CREATED         SIZE
redis               latest                    e40e2763392d   2 weeks ago     138MB
...

We can then save it locally:

F:\>docker save redis:latest --output E:\docker-images\redis-7-2-3-latest.tar

I copy redis-7-2-3-latest.tar to Ubuntu 22.10’s Public/ directory, and load it up with the command:

$ sudo docker load --input Public/redis-7-2-3-latest.tar

Running the Redis CLI

There’re two (2) ways to run the Redis CLI: Bash mode interactive and directly via the container.

❶ Bash mode interactive.

Given that the Redis container discussed above is running, get into the container Bash mode interactive with the command:

▶️Windows 10: docker exec -it redis-docker bash
▶️Ubuntu 22.10: $ sudo docker exec -it redis-docker bash

The prompt changes to something like the following root@b764904a70a6:/data#. Now run redis-cli:

root@b764904a70a6:/data# redis-cli

The prompt changes to 127.0.0.1:6379>. 🚀 Run the ping command, we should get the PONG response.

Now try setting some data and retrieving it using the following two (2) commands:

127.0.0.1:6379> SET mykey "Hello\nWorld"
127.0.0.1:6379> GET mykey

To quit, use the exit command until we get returned to the console.

❷ Directly via the container.

▶️Windows 10: docker run -it --network redis-network --rm redis redis-cli -h redis-docker
▶️Ubuntu 22.10: $ sudo docker run -it --network redis-network --rm redis redis-cli -h redis-docker

💥 Note the --network redis-network parameter, without it, we won’t be able to run the CLI via the container.

The prompt changes to 127.0.0.1:6379>, we can now repeat the above command sequence.

The screenshot below shows the running and the output of the processes just discussed:

092-02.png

We can now stop the container with:

▶️Windows 10: docker stop redis-docker
▶️Ubuntu 22.10: $ sudo docker stop redis-docker

The in-memory data’ll be written to dump.rdb in the database directory specified above. We can view it as text. The above test produces something similar to the content below:

REDIS0011�      redis-ver7.2.3�
redis-bits�@�ctime�]�eused-mem� Xaof-base���mykey
                                                 Hello

Restart the container again with:

▶️Windows 10: docker restart redis-docker
▶️Ubuntu 22.10: $ sudo docker restart redis-docker

Try the CLI again, and run the command get mykey, the data should still be there. New data are written to the same file.

Rust and Python test code

The test code is extremely simple, taken directly from respective official documentations. The primary purpose of the test code is to verify that we can programmatically access the Docker Redis server.

Rust test code

The Redis official page Connect with Redis clients doesn't mention Rust. Crate redis seems popular on https://crates.io/.

The Rust test code is taken directly from the crate redis official documentation.

Content of Cargo.toml:
[package]
name = "redis"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
redis = "0.24.0"
Content of src/main.rs:
use redis::Commands;

fn do_something() -> redis::RedisResult<i32> {
    let client = redis::Client::open("redis://127.0.0.1/")?;
    let mut con = client.get_connection()?;

    let _ : () = con.set("my_key", 42)?;
    let res = con.get("my_key")?;

    Ok(res)
}

fn main() {
    match do_something() {
        Ok(i) => println!("result: {}", i),
        Err(e) => println!("Error {}", e)
    }
}

The screenshot below shows the output of the program, and some CLI tests to verify that the program has successfully written data to the database file:

092-03.png

Python test code

The test code is taken from the following official documents: Redis Python guide and GitHub redis-py.

Activate a virtual environment and install the Python redis-py package:

pip install redis
Content of redis1.py:
import redis

def some_thing():
    r = redis.Redis(host='localhost', port=6379, decode_responses=True)

    print('my_key value, set previously: ', r.get('my_key'))
    print('mykey value, set previously: ', r.get('mykey'))

    r.set('python', 'Python and Redis')
    print('python value, just set: ', r.get('python'))

some_thing()

The command to run the redis1.py script:

▶️Windows 10: (venv) F:\pydev>venv\Scripts\python.exe redis1.py
▶️Ubuntu 22.10: (venv) behai@hp-pavilion-15:~/pydev$ venv/bin/python redis1.py

Output on Windows 10 and Ubuntu 22.10:


Unable to Apply Custom Config: no Remote Connection

The Redis Docker Official Image states that we can run the image with a custom configuration file which lives locally on the host machine:

Alternatively, you can specify something along the same lines with docker run options.

$ docker run -v /myredis/conf:/usr/local/etc/redis --name myredis redis redis-server /usr/local/etc/redis/redis.conf

Where /myredis/conf/ is a local directory containing your redis.conf file. Using this method means that there is no need for you to have a Dockerfile for your redis container.

The mapped directory should be writable, as depending on the configuration and mode of operation, Redis may need to create additional configuration files or rewrite existing ones.

And I've taken the example configuration from this official page Redis configuration file example. And the location of the custom configuration file in each host machine is:

Windows 10: E:\redis-config\redis.conf
Ubuntu 22.10: /home/behai/Public/database/redis-config/redis.conf

The command to run with a custom configuration file:

▶️Windows 10: docker run --publish=6379:6379 --network redis-network -d -it --rm --mount type=bind,source=//d/database/redis,target=/data -v //e/redis-config:/usr/local/etc/redis --name redis-docker redis redis-server /usr/local/etc/redis/redis.conf
▶️Ubuntu 22.10: $ sudo docker run --publish=6379:6379 --network redis-network -d -it --rm --mount type=bind,source=/home/behai/Public/database/redis,target=/data -v /home/behai/Public/database/redis-config:/usr/local/etc/redis --name redis-docker redis redis-server /usr/local/etc/redis/redis.conf

It does not report any problem, but checking the status with:

▶️Windows 10: docker logs redis-docker
▶️Ubuntu 22.10: $ sudo docker logs redis-docker

shows the following warning:

Warning: Could not create server TCP listening socket ::1:6379: bind: Cannot assign requested address

👎 We won’t be able to run the CLI directly via the container as discussed. 🚀 However, the Bash mode interactive still works.

From my Windows 10 machine, I can’t programmatically connect to the Redis container running on Ubuntu 22.10 – see Rust and Python test code section.

– I just change localhost to the IP address of the Ubuntu 22.10 machine, and also allow traffics through port 6379 with command sudo ufw allow 6379.

I assume that the server has been configured to recognise only traffics from localhost? A custom configure would help to overwrite this, but I’m not able to do this… This is a task for another day.

Other Docker Posts Which I've Written

  1. Synology DS218: sudo password and unsupported Docker problems update... -- I have been updating the DSM without running sudo or docker. I have just tried both recently, both failed. I'm describing how I've managed to fix these two problems.
  2. Docker Compose: how to wait for the MySQL server container to be ready? -- Waiting for a database server to be ready before starting our own application, such as a middle-tier server, is a familiar issue. Docker Compose is no exception. Our own application container must also wait for their own database server container ready to accept requests before sending requests over. I've tried two ( 2 ) “wait for” tools which are officially recommended by Docker. I'm discussing my attempts in this post, and describing some of the pending issues I still have.
  3. Synology DS218: unsupported Docker installation and usage... -- Synology does not have Docker support for AArch64 NAS models. DS218 is an AArch64 NAS model. In this post, we're looking at how to install Docker for unsupported Synology DS218, and we're also conducting tests to prove that the installation works.
  4. Python: Docker image build -- install required packages via requirements.txt vs editable install. -- Install via requirements.txt means using this image build step command “RUN pip3 install -r requirements.txt”. Editable install means using the “RUN pip3 install -e .” command. I've experienced that install via requirements.txt resulted in images that do not run, whereas using editable install resulted in images that do work as expected. I'm presenting my findings in this post.
  5. Python: Docker image build -- “the Werkzeug” problem 🤖! -- I've experienced Docker image build installed a different version of the Werkzeug dependency package than the development editable install process. And this caused the Python project in the Docker image failed to run. Development editable install means running the “pip3 install -e .” command within an active virtual environment. I'm describing the problem and how to address it in this post.
  6. Python: Docker image build -- save to and load from *.tar files. -- We can save Docker images to local *.tar files, and later load and run those Docker images from local *.tar files. I'm documenting my learning experimentations in this post.
  7. Python: Docker volumes -- where is my SQLite database file? -- The Python application in a Docker image writes some data to a SQLite database. Stop the container, and re-run again, the data are no longer there! A volume must be specified when running an image to persist the data. But where is the SQLite database file, in both Windows 10 and Linux? We're discussing volumes and where volumes are on disks for both operating systems.
  8. Docker on Windows 10: running mysql:8.0.30-debian with a custom config file. -- Steps required to run the official mysql:8.0.30-debian image on Windows 10 with custom config file E:\mysql-config\mysql-docker.cnf.
  9. Docker on Windows 10: mysql:8.0.30-debian log files -- Running the Docker Official Image mysql:8.0.30-debian on my Windows 10 Pro host machine, I want to log all queries, slow queries and errors to files on the host machine. In this article, we're discussing how to go about achieving this.
  10. pgloader Docker: migrating from Docker & localhost MySQL to localhost PostgreSQL. -- Using the latest dimitri/pgloader Docker image build, I've migrated a Docker MySQL server 8.0.30 database, and a locally installed MySQL server 5.5 database to a locally installed PostgreSQL server 14.3 databases. I am discussing how I did it in this post.

I hope you find the information in this post helpful. Thank you for reading. Wishing you a Merry Christmas and a New Year full of Happiness and Health. Stay safe as always.

✿✿✿

Feature image source: