building packages with docker

This is a simple idea I had while waiting for a build to complete.

The background
Its common to use dpkg-buildpackage inside of a chroot managed by pdebuild. The pdebuild script
takes a minimal base image tarball and installs all dependencies in it required to
build your package.

The build dependencies come from debian/control Build-Depends section. The package being
built is a python application using virtualenv. A lot of the packages come from apt however.
There is a bunch of python pip/easy install work performed too.

Needless to say this takes quite some time to do since extracting a .deb and installing
it is a pretty expensive operation when there is a lot of dependencies.

Obverve the following times

because i’m not interested in explaining how the other 2 method work, i’ll leave that out. However, let me
explain how the docker build works.

docker

The idea is to exploit the layered file system of containers to provide build dependencies. Since
its a copy on write file system, this means providing a container with all build deps present is
incredibly fast.

Dockerfile

FROM ubuntu
RUN apt-get update \
   && apt-get install -y dpkg-dev


# This is the key line, it installs the build dependencies for your application!
RUN apt-get build-dep -y --force-yes YOUR_PACKAGE

RUN useradd packaging \
   && mkdir -p /packaging \
   && chown packaging /packaging

USER packaging
ADD build.sh /bin/build.sh

ENTRYPOINT [ "/bin/build.sh" ]

build.sh

#!/bin/bash

echo "[build.sh] $@"

set -x

cd /packaging
pwd
tar vzxf -
cd package
dpkg-buildpackage

Then to invoke the build we stream the contents at a tar.gz into the container which streams
it to disk and builds the package.

package_stream ()
{
    git archive HEAD --format tar --prefix=package/ | gzip -9
}

Finally, this is the final command that runs the build

  time package_stream | docker run -i debbie