With version 4.0 Redis, the former key-value / data structure store, is now capable of pluggable modules which can be loaded into Redis and thus be used just as regular "native" commands and data types.
Most excitingly Redis can now be extended to e.g. store and read JSON or graphs, for machine learning or for full-text search.
As Salvatore Sanfilippo puts it:
Finally it is possible to use Redis as a framework to write networked services without reinventing everything from scratch. Modules can extend Redis with new functionalities and data structures, implement types which are exactly like the native types (persisted in the RDB, rewritten in the AOF, ...), and there is experimental support for blocking and threaded slow operations. (source)
Overview
As a basic example this post will examine how to use the redis password module
along with the official redis docker image in a docker container and how to access it via redis-cli
or NodeJS clients (node_redis
and ioredis
).
Dockerfile
Far from perfect, but as a proof of concept you could use a Dockerfile
more or less like this:
FROM redis:latest # Version 4.0 or above
ENV TERM=XTERM
RUN apt-get -y update
RUN apt-get install -y wget unzip cmake
RUN cd /tmp \
&& wget https://github.com/RedisLabsModules/password/archive/master.zip \
&& unzip master.zip -d /redis-password \
&& cd /redis-password/password-master \
&& make
RUN apt-get purge -y wget unzip cmake \
&& apt-get autoremove -y \
&& apt-get autoclean -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
USER redis
CMD ["redis-server", "--appendonly", "yes", "--requirepass", "yourBetterPW", "--loadmodule", "/redis-password/password-master/password.so"]
(You might probably want to choose something better then the install target given here ... and you definitely should use docker secrets
for the --requirepass
password.)
Docker Image and Container
After finishing the Dockerfile
you need to build
the image, then run
the container, and optionally inspect its logs
:
docker build -t <img_name> .
docker run -itd <img_name>
docker logs <ctr_id>
For external access use -p 6379:6379
and for data persistence use -v <...>
with a host bind
or named volume
as parameter.
If you had previously downloaded redis:latest
(before version 4.0) and get strange errors on docker run
like
*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 4
>>> 'loadmodule "/redis-password/password-master/password.so"'
Bad directive or wrong number of arguments
make sure to either docker pull redis:latest
again or to use docker build
with the --no-cache
option or to just use FROM redis:4
in your dockerfile. On correct startup the redis logs
should show something like:
<...>
Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
<...>
Server initialized
<...>
Module 'password' loaded from /redis-password/password-master/password.so
Ready to accept connections
Docker CLI Access
While the interactive container is running you can open a new shell
to connect to it, execute redis-cli
, authenticate and then set and check the password key value
pair:
docker exec -it <ctr_id> /bin/bash
redis-cli
AUTH yourBetterPW # returns OK
PASSWORD.SET 1234 xxx # returns OK
PASSWORD.CHECK 1234 xxx # returns (integer) 1
PASSWORD.CHECK 1234 xxxs # returns (integer) 0
There are equivalent commands for hash maps
: PASSWORD.HSET
and PASSWORD.HCHECK
.
NodeJS Access
In order to access these redis module commands from a remote NodeJS client you need to use the client.send_command()
command (docs) in case of node_redis
and redis.call()
(github issue) in case of ioredis
.
Summary
Although this is only a basic proof of concept this example shows the combined beauty of redis and docker.
A few years back something similar would have taken several man days, virtual machines, configurations, licenses etc. Today you can get it configured within a couple of hours and by some lines of code. And it starts and stops within seconds. Ah ... and yes ... thanks to its written manifest it is reliably reproducible.
Update: There is also a follow-up blog post now available:
Redismod - A Redis Docker Image with Redis Modules
Further Information
Redis Version 4.0:
https://groups.google.com/forum/#!msg/redis-db/5Kh3viziYGQ/58TKLwX0AAAJ
http://sdtimes.com/redis-4-0-improves-limitations/
Redis Modules:
https://redis.io/modules
http://redismodules.com
https://redis.io/topics/modules-intro
http://redismodules.com/modules/password/
https://github.com/RedisLabsModules/password
Redis NodeJS Clients:
https://github.com/NodeRedis/node_redis#clientsend_commandcommand_name-args-callback
https://github.com/luin/ioredis/issues/500
Redis Official Docker Image:
https://hub.docker.com/_/redis/
https://github.com/docker-library/redis/blob/1d6d5acf99aedd42aa0195ad5f22b8ffa6841f96/4.0/Dockerfile
Docker Cheat Sheet:
https://github.com/daten-und-bass/docker-cheat-sheet
Docker Secrets How-To:
https://daten-und-bass.io/blog/using-docker-secrets-with-nodejs/
Redismod - A Redis Docker Image with Redis Modules:
https://daten-und-bass.io/blog/redismod-a-redis-docker-image-with-redis-modules/