Containers & Redis – Running Redis on Windows with Docker

This is a Story About How Docker Saves Redis on Windows

This is a guest blog by Jingya Wang, who is a Microsoft Student Partner at Imperial College London.

clip_image002

Introduction

image

The first time I came across Docker, was during my internship at Microsoft Research Asia. The project involves the use of Redis, and ‘the Redis project does not officially support Windows’! So you may image how hard it is to start the project at the beginning.

Finally, Docker saves my life! Even since then, Docker is the first thing I will go to when running into software compatibility problem. In this blog, let’s use Redis as an example to introduce essential concepts such as docker containers, commands and different flags, and hopefully after reading it, you will appreciate Docker as much as I do.

Redis using Docker

When I start researching on how to run redis server using docker, a lot of solutions popped up but few told you how to use run redis server and correctly connect it with you Node.js code. We will walk through this set up step by step here.

The Simplest Way

The basic command line to run Redis using Docker is,

> docker run redis

Some formal definitions are given below, summarized from the Docker docs https://docs.docker.com/engine/getstarted/step_two/.

· run creates and runs a docker container.

· redis tells docker which image to load into the container.

· An image is a filesystem and parameters to use at runtime.

· A container is a running instance of an image. It wraps a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries. This guarantees that the software will always run the same, regardless of its environment. Please see more details of Docker container https://www.docker.com/what-docker.

The key point is the docker container, which allows me to run Redis on Windows, even if the Redis project does not officially support Windows. The Redis image is pulled from the Docker Hub, and you should get a similar figure in the terminal as seen in Figure 1, saying the Redis ‘server is now ready to accept connections on port 6379’!

Figure 1: Redis server is now ready to accept connections on container port 6379

image

If you open another terminal and type in

> docker ps

All information about this running container is retained. As we did not specify a name for the container using the --name flag, Docker assigns a random name to the container, in this case, desperate_northcutt.

Figure 2: docker ps

image

The Simplest Way with a Serious Problem

To run Redis in this way, you cannot use this NoSQL Data Structure Server in any web applications, simply because it is in a Docker container, which ‘isolates applications from one another and the underlying infrastructure, while providing an added layer of protection for the application.’

To be able to create a connection between your Node.js code and the Redis server, we also need flag -p to docker run redis.

-p Flag

-p flag binds the container port to a specific port, which means now you can createClient() in Node.js using default host 127.0.0.1 and port 6379. In both Figure 1 and 2, the port number 6379 is referred as the container port. So the configuration of -p flag follows hostPort:containerPort.

> docker run –p 6379:6379 redis

Notice how the information about PORTS changes from Figure 2 to Figure 3.

Figure 3: docker ps with -p flag

image

The port number inside the container does not need to match the port number exposed on the outside of the container. Hence we may also run

> docker run –p 6379 redis

A random host port number will be assigned to the container, and it can be found out by running

>docker port $CONTAINER ID

6379/tcp -> 0.0.0.0:32770

Create Redis Client in Node.js

After binding the container port to the host port, we are able to create connection between Docker Redis image and Node.js in the following way,

Figure 4: connection between Docker Redis image and Node.js

image

For the case where the host port is randomly assigned by Docker, the Redis client can be created by specifying the port number,

2 var client = createClient({port: ‘32770’});

Linking Containers

We may also choose to use container links to provide access to our Redis database, create multiple Redis clients to securely transfer or share information about one container to another.

First, let’s create a container called redis1 running redis image, where flag –d specifies the container to run on background, meaning you will not an image in Figure 1.

> docker run –d --name redis1 redis

Second comes to the linking part. The key part is ‘--link redis1:redis’, linking container client1 and redis1 together. Another unseen part is –it flag, which can be separated as -i and -t, must be used together for interactive processes like a shell. sh at the end allows us to go into the shell and run both Redis server and redis-cli.

> docker run -it -p 6379:6379 --link redis1:redis --name client1 redis sh

In similar manner in a new terminal, a second Redis client can be created and link to redis1 container as well. Here, we will allow Docker to assign a host port to the container instead of still specifying it as 6379.

> docker run -it -p 6379 --link redis1:redis --name client2 redis sh

Now both client1 and client2 are linked to redis1, we can go into the redis-cli environment and see how information is shared between two clients. Play with basic Redis commands such as GET and SET, and you will find out that the key-value pair set in client1 can be retained in client2.

# redis-cli –h redis

client1

redis:6379> SET key1 value1

OK

client2

Redis:6379> GET key1

value1

This subsection is based on the Docker Tutorial Series: Part 8: Linking Containers. If interested, please see https://rominirani.com/docker-tutorial-series-part-8-linking-containers-69a4e5bf50fb#.s7izi6ujd for further information.

To conclude with, linking containers with –p flag should be one of the powerful ways to run Redis server using Docker and connect it to your Node.js code. However, there are other ways such as linking Ubuntu with Redis to ‘Dockerize a Redis service’ https://docs.docker.com/engine/examples/running_redis_service/#/run-the-service. You may want to explore this approach depending on the need. For basic uses of Redis as NoSQL Data Structure Server, setting up linking client containers seems to be sufficient.

Conclusion

For sure there are other ways to solve this problem, such as ssh to a Linux or Mac machine and run your Redis server there, or following what is suggested on the Redis download page https://redis.io/download. But comparing these approaches, running Redis using Docker on Windows seems to be the cheapest approach, without the requirement of another Linux or Mac machine, or Win64 API environment.

There are always arguments going on with which OS is best for programming, and one of the disadvantages of Windows is this poor software compatibility. With Docker, especially its light-weighted Docker containers, it certainly makes up this disadvantage and makes life programming on Windows much easier.

More generally speaking, regardless of the environment, whenever you run into a software compatibility problem, remember to try docker run and see if it will save your day!