14 avril 2014

Jenkins meets Docker - round 2

On my previous blog post I explained how to use docker from Jenkins.

I can see some issues with this setup :

  1. You have to register the docker image you want to use as a slave in Jenkins global configuration, and rebuild the image when your environment requires some changes. 
  2. Dockefile has to define a ssh server, just to act as a jenkins slave, unrelated to your project needs.
  3. Docker plugin isn't elastic, even being a "Cloud" Jenkins plugin. It relies on a static docker-enabled host to run containers. I'd like to keep the Cloud principle to get resources as needed.

So, please welcome oki-docki jenkins plugin. This is still an experimental, unreleased, work-in-progress, use-at-your-own-risk plugin, but here's the concept :

You use your SCM to store both project source code, build script and a Dockerfile that describes your build environment. oki docki will use your Dockerfile to build+run a container and execute build script.

Plugin actually

  • checks project workspace for a Dockerfile
  • computes its hash, to detect changes
  • search for an existing docker image to match, build one if required
  • run a container, mounting build workspace in container as /var/workspace
  • executes build script

You may notice the docker image isn't pushed to a repository. This is intentional. I like the idea I can rebuild my docker image at any time from scratch, not relying on some binary deployed somewhere. Thanks to Docker incremental build, this isn't such time-consuming.

Benefits :

  1. no need to setup anything on jenkins, just have docker-enabled slaves. I'm using a "docker" label for this purpose. This one can benefit from jenkins Cloud slave providers.
  2. Dockerfile just defines requirements to build your project. All yours to select a specific JDK, system packages or nodejs version. The same Dockerfile can be used by developers to get a ready-to-use development environment.
  3. project Dockerfile is stored in SCM, with application code and build scripts, and all is kept in sync without manual steps. You can have a distinct Dockerfile in a branch if needed.

The current implementation is more a Proof-of-concept than a production-ready plugin, but already let you run a build inside Dockerfile. My initial goal was to start the container and then let jenkins run any regular build steps inside, but this require some Jenkins-remoting redirection hack, which development skills I don't have. On the other side, I also think it make sense to define your CI process as a script store in SCM, not relying on a set of build steps configured in jenkins (must admit I like travis-ci approach on this topic).

I plan to demonstrate this at DevoxxFrance during my talk "La révolution Docker" - assuming I don't break my environment in the meantime :)