Using Docker to build and run a bleeding-edge version of a software
  2015-11-15

Docker logo

Purpose

Using Docker to build and use the latest version of a software of your choice, without messing up your workstation with build or runtime dependencies you don’t need.

Why?

Building the latest version of a software may involve two things:

  • To install its build dependencies (gcc, build-essential, autotools, libA-devel, …)
  • To install its runtime dependencies (libA, libB, …), which required version may not be available as a package in your Linux distribution.

Thus you have to deal with Github repositories clones, custom prefixes (~/dev/libA, ~/dev/libB) through the build/install process, and eventually LD_LIBRARY_PATH adjustments once you start your software, to ensure the correct runtime version of a library is used.

I bet installing everything to /usr, in a dedicated system, would make the whole process easier, isn’t it?

Docker is a low-footprint (compared to full VMs) solution to this problem. Everything (dependencies, work directory, compilations) will be restricted to a Docker container, and you can even run graphical applications.

For illustration purposes, I’m going to show you how to build and start the latest version of Fontforge, which is a graphical font editor.

I will use Archlinux for the host and Debian for the Docker container.

Requirements

  • Docker fondamentals (Docker documentation is well-written)
  • A working Docker environment, under a Linux host (for X11), the distribution doesn’t matter. It’s already explained in details everywhere on Internet, so I’m not going to explain it here.

Steps

Dockerfile

On the host system (Archlinux for me), start an editor on the Dockerfile:

$ mkdir dockerfiles && cd dockerfiles && **<favorite_editor>** Dockerfile

Then use the software documentation for the required steps to build the latest version (it has one eh?) and Best practices for writing Dockerfiles to write your Dockerfile.

You are hardly going to need something else than the RUN instruction. Luckily, Fontforge provides a step-by-step guide to build Fontforge from Git source code.

This is really simple, here is mine below for building Fontforge, adjust yours accordingly.

FROM debian:jessie
MAINTAINER Loic Pefferkorn <loic-docker@loicp.eu>
WORKDIR /root


# From official build instructions
# https://github.com/fontforge/fontforge/blob/master/INSTALL-git.md

# Fontforge build dependencies
RUN apt-get update && apt-get install -y \
    sudo \
    packaging-dev \
    pkg-config \
    python-dev \
    libpango1.0-dev \
    libglib2.0-dev \
    libxml2-dev \
    giflib-dbg \
    libjpeg-dev \
    libtiff-dev \
    uthash-dev \
    libspiro-dev \
    build-essential \
    automake \
    flex \
    bison && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Optional: install fontforge runtime dependencies
RUN apt-get install -y $(apt-cache depends fontforge|awk '/Depends/ {print $2}')  && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
    
# Build libspiro dependency
RUN git clone https://github.com/fontforge/libspiro.git && \
     cd libspiro && \
     autoreconf -i && \
     automake --foreign -Wall && \
     ./configure --prefix=/usr  && \
     make install 

# Build libuninameslist dependency
RUN git clone https://github.com/fontforge/libuninameslist.git && \
     cd libuninameslist && \
     autoreconf -i && \
     automake --foreign && \
     ./configure --prefix=/usr && \
     make install

# Finally build Fontforge 
RUN git clone https://github.com/fontforge/fontforge.git && \
     cd fontforge && \
     ./bootstrap && \
     ./configure --prefix=/usr && \
     make install && \
     ldconfig

# Trick found on http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
# update the uid/gui values below accordingly to your user on the host
ENV uid 1000
ENV gid 100
ENV username developer
RUN /usr/sbin/useradd --uid $uid --gid $gid --create-home $username && \
    echo "$username ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer

USER developer
ENV HOME /home/developer
CMD /usr/bin/fontforge

Everything is split across several lines and &&‘ed, to reduce layers and for the sack of producing meaningful diffs for further Dockerfile updates. sudo is just here if you want to play in the container as root later.

Build the Docker image

# docker build --tag fontforge

Run the container

To export the display system outside the container, we share the X11 host socket and $DISPLAY variable with the container.

Note: Sharing the X11 socket with the container is a comfort solution, not a secure one, because the container can read all your inputs (mouse, keyboard)

docker run -ti --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix fontforge

Below I start the Docker image, then display the “About” dialog of FontForge to show the Git version:

Docker screencast