You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
webdiss/docs/webdis-docker-serve-rdb-fil...

4.8 KiB

Serving data from a Redis RDB snapshot over HTTP with Webdis and Docker

Redis can produce snapshots of its dataset using the SAVE command, which creates a file usually named dump.rdb. This page explains how to take such a file and make its contents available over HTTP with Webdis and Redis running in a single Docker container.

TL;DR: if you just need the command

First, create a directory on the host machine and copy dump.rdb into it:

$ mkdir redis-data
$ cp dump.rdb redis-data/

Then, run the Webdis container with this directory mounted as /var/lib/redis:

$ docker run --name webdis-local-data --rm -d -p 127.0.0.1:7379:7379 \
      -v$(pwd)/redis-data:/var/lib/redis nicolas/webdis:latest

The contents of the dump.rdb file are now accessible over HTTP on port 7379.

Stop the container with:

$ docker stop webdis-local-data

How this works

For a full explanation, please read on.

Structure of the Webdis container

The Docker images for Webdis are built to help users discover Webdis and get started quickly. For this reason, they embed a Redis server and the Webdis process running alongside Redis provides access to its keys over HTTP.

To start Redis with an existing dump.rdb file, we first need to find the directory used by Redis to save its data. This directory is configured by the dir entry in redis.conf (see documentation), so all we have to do is grep for it in redis.conf:

$ docker run --rm -ti nicolas/webdis:latest cat /etc/redis.conf | grep ^dir
dir /var/lib/redis

Side note: a tool like Dive can also be helpful to explore Docker images.

Creating a dump.rdb file

To demonstrate the reloading of a dump.rdb file, we'll first need to create one.

In order to have access to /var/lib/redis from the host, we can run the Docker container with a mounted volume such that a local directory on the host (we'll call it redis-data) will be accessible as /var/lib/redis from inside the container. So let's create this directory, run Webdis with the custom mount, write a couple of keys, save the dump.rdb file, and stop the container:

$ mkdir ./redis-data

$ docker run -d --rm --name webdis-local -v$(pwd)/redis-data:/var/lib/redis \
    -p127.0.0.1:7379:7379 nicolas/webdis:latest
f95a587c644a7b8b838eee2ac60b9bb92613e3aa4a5cc6347ca61fdce324c477

$ curl -s http://127.0.0.1:7379/SET/hello/world
{"SET":[true,"OK"]}
$ curl -s http://127.0.0.1:7379/SET/foo/bar
{"SET":[true,"OK"]}
$ curl -s http://127.0.0.1:7379/SAVE
{"SAVE":[true,"OK"]}

$ docker stop webdis-local
webdis-local

After writing the keys hello and foo and asking Redis to persist its data, we now have dump.rdb in our local directory and we can verify that it contains the keys we've just written:

$ ls redis-data/
dump.rdb

$ xxd redis-data/dump.rdb
00000000: 5245 4449 5330 3030 39fa 0972 6564 6973  REDIS0009..redis
00000010: 2d76 6572 0536 2e32 2e36 fa0a 7265 6469  -ver.6.2.6..redi
00000020: 732d 6269 7473 c040 fa05 6374 696d 65c2  s-bits.@..ctime.
00000030: 5765 dc62 fa08 7573 6564 2d6d 656d c281  We.b..used-mem..
00000040: a00e 00fa 0c61 6f66 2d70 7265 616d 626c  .....aof-preambl
00000050: 65c0 00fe 00fb 0200 0005 6865 6c6c 6f05  e.........hello.       <--- hello…
00000060: 776f 726c 6400 0366 6f6f 0362 6172 ffaf  world..foo.bar..       <--- :world and foo:bar
00000070: ebb4 9ade 2632 58                        ....&2X

The docker stop command not only stopped the container, but also removed it entirely since we had started it with --rm. While this means that the container itself is gone, we still have dump.rdb in our local directory and we can run a new container with this file already pre-loaded into Redis.

Running a new container with our dump.rdb file

To inject this file into a new Webdis container, we just have to start it the same way except this time our /var/lib/redis directory will contain a file for Redis to load at startup. We'll use a different container name here, just to make it obvious that we're not reusing the previous one:

$ docker run -d --rm --name webdis-new -v$(pwd)/redis-data:/var/lib/redis \
    -p127.0.0.1:7379:7379 nicolas/webdis:latest
4002cf5a699150875efa445a1e862865886b2515bbab6ad1d556ebd5f0234ae1

$ curl -s http://127.0.0.1:7379/GET/hello
{"GET":"world"}
$ curl -s http://127.0.0.1:7379/GET/foo
{"GET":"bar"}

$ docker stop webdis-new
webdis-new

This shows that we successfully re-imported dump.rdb as the source data that Redis will start with in a new container.