Docker Latent Buildslave

This was merged in with PR1341 and PR1344.

This page to host my (Ben) notes about my work on the DockerLatentSlave. However, this page does not belong to me, and everyone is invited to post their though / improvements / progress (?) there !

I'm tracking my commits here:

Issue #2956 was made about that. #2970 Was about the first troubles I had setting this up.

The following class can be taken as a base for the work in this direction: However, there is quite some work to be done in order to get it working.


  • docker-py (not even docker itself)
  • Some docker running somewhere, and having its socket available to the master.
  • an image name that can be booted by docker and run a build.

My setup:

  • buildbot master in a virtualenv (pip install --develop master) + docker-py installed pip install docker-py
  • CoreOS running inside virtualbox (boot2docker should work as well), and exporting the socket on an external port ($expose_docker_tcp=2375 in the config.rb file of coreos)
  • CoreOS started via Vagrant vagrant up

Login to CoreOS vagrant ssh, make an image docker build -t wheezy_slave - < Dockerfile. I used the following Dockerfile:

FROM debian:wheezy
MAINTAINER Benoît Allard <>
RUN apt-get update && apt-get install -y \
   python-dev \
RUN pip install buildbot-slave
RUN groupadd -r buildbot && useradd -r -g buildbot buildbot
RUN mkdir /buildslave && chown buildbot:buildbot /buildslave
USER buildbot
WORKDIR /buildslave
RUN buildslave create-slave . herbert docker pass
USER root
RUN ln -s /buildslave/twisted.log /dev/stdio
USER buildbot
ENTRYPOINT ["/usr/local/bin/buildslave"]
CMD ["start", "--nodaemon"]

I would have prefered not hardcoding my master hostname there ...

Using the following code, we can check if the image is available to docker via our socket:

from docker import client
c = client.Client(base_url="http://localhost:2375")
i = c.create_container('wheezy_slave')
# Optionally examine the logs of the master

I have the following slave definition in my config:

import dockerslave; reload(dockerslave)


And next to my master.cfg

Next, we need a builder that has some work for our slave. This is the definition I'm using:

c['builders'].append(util.BuilderConfig(name="GH-1288", slavename="docker", factory=util.BuildFactory(
    [steps.ShellSequence([util.ShellArg('echo a; echo b 1>&2; exit 1', logfile='log')] * 5 +
    [util.ShellArg(['echo', 'a'], logfile='log')] +
    [util.ShellArg('echo a; echo b 1>&2; exit 1', logfile='log')] * 5)]
c['schedulers'].append(schedulers.ForceScheduler(name="GH-1288", builderNames=['GH-1288']))

(There are simpler ones, but this one will do is as well)

Start your master. The following line should come in the logs:

2014-11-08 12:10:49+0100 [-] Latent buildslave docker attached to GH-1288
2014-11-08 12:10:49+0100 [-] adding scheduler 'GH-1288'

Well, now, force a build and start debugging ...

Last modified 3 years ago Last modified on Nov 15, 2014, 5:09:05 PM