A Redis 4 Docker Image Proposal

André Fernandes
May 16, 2017 · 2 min read

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!

André Fernandes

Written by

@vertigobr Founder & CTIO, disrupting things for fun.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade