A Redis 4 Docker Image Proposal

The need to use build tools on intermediary steps of many Docker images always left a bad taste on otherwise beautiful work on producing minimal and reusable Docker images for everyone.

Multi-staged builds are a new feature from Docker 17.05 that come to the rescue. Now binary artifacts can be built based on a Dockerfile stage and reused as COPY artifacts on another stage. This same trick could only be achieved by somewhat complicated scripts and pipelines on several different tools — having a single Dockerfile is a lot better!

Well, today I had to use a beta version of Redis 4 and none was available. I could simply steal the Dockerfile from redis:3 official image and slightly adapt it, or I could try something else with a little more fun.

First Stage — Redis 4 build

The original Dockerfile from redis:3 image goes into a lot of trouble to (1) install build tools, (2) build source code and (3) remove build tools on a single RUN command. That serves the purpose of preserving a smaller image size, but build time and readability suffer a lot.

The snippet below illustrates what current redis:3 Dockerfile does (it was changed and reduced for readability):

FROM debian:jessie
# ...
RUN buildDeps=gcc libc6-dev make && \
apt-get update && \
apt-get install -y $buildDeps — no-install-recommends && \
make -C /usr/src/redis && \
make -C /usr/src/redis install && \
apt-get purge -y — auto-remove $buildDeps

Why go through all this work if we can pick anything else as a starting point? The first stage can be simple as that:

FROM buildpack-deps:jessie as builder
# ...
RUN make -C /usr/src/redis && \
make -C /usr/src/redis install

Second Stage — Redis 4 final image

Binary artifacts from the first stage build will be right there where "make install" wrote them, so a second stage can pick them easily:

FROM debian:jessie
# ...
COPY --from=builder /usr/local/bin/redis* /usr/local/bin/

The complete sources for this Docker image can be found at https://github.com/vertigobr/redis4. The heavy work was a shameless copy from the original work from the current redis:3 Dockerfile, what I did was simply to rearrange things a little bit.

What about Redis Modules?

Same thing — builder image on first stage, base image on second stage.

Redis modules are a new thing and AFAIK you must build them on your own, but once built they are a single binary file. Perfect case for a multi-staged build:

# FIRST STAGE
FROM buildpack-deps:jessie as builder
RUN mkdir -p /src && \
cd /src && \
git clone https://github.com/RedisLabsModules/rejson.git && \
cd /src/rejson && \
make
# FINAL STAGE
FROM vertigo/redis4
COPY --from=builder /src/rejson/src/rejson.so /opt/redis_modules/rejson.so
RUN sed “s/\”\$0\”/\”\$0\” \
--loadmodule \/opt\/redis_modules\/rejson\.so/” \
-i /usr/local/bin/docker-entrypoint.sh

First stage uses a "buildpack" image to build the module "rejson.so", second stage just adds it to the redis4 image we produced before.

The code for these samples can be found at https://github.com/vertigobr/redis4 (Redis 4 image) and at https://github.com/vertigobr/rejson (ReJSON on Redis 4 image).

Have fun!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.