Our CI server is getting a bit overloaded, and I didn’t want to install more packages on it to test our new go projects. Since we are also playing a lot with Docker lately, it felt natural to use it to run test suites and determine coverage of go projects. Just by installing docker on our private CI server, all our team is now able to add various projects, with different versions, without interfering with other projects or environments.
This first step was to define a common Go base image for our go projects :
# Prefer debian over ubuntu FROM debian:wheezy # Let's install go just like Docker (from source). RUN apt-get update -q RUN apt-get install -qy build-essential curl git mercurial bzr RUN curl -s https://go.googlecode.com/files/go1.2.src.tar.gz | tar -v -C /usr/local -xz RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1 ENV PATH /usr/local/go/bin:/go/bin:$PATH ENV GOPATH /go # we're using godep to save / restore dependancies RUN go get github.com/kr/godep # Cover is used in almost all projects too RUN go get code.google.com/p/go.tools/cmd/cover WORKDIR /go
Let’s create a Makefile along to this Dockerfile:
all: build build: docker build -no-cache -rm -t docker:5000/go:1.2 . run: docker run -rm docker:5000/go:1.2
We can argue on the no-cache parameter here, but since the second line is a “apt-get update”, we should not cache this. If we decide to modify th Dockerfile later, and add a new debian package with “apt-get install”, it will possibly fail because it won’t be available anymore for download.
Anyway, we now have our docker:5000/go:1.2 image ready to be used. We won’t use this image directly, but instead share it in other docker images.
Let’s Create our go project
Let’s create a new “go-example” project on our git server. The local path in $GOPATH will be something like “$GOPATH/src/gitlab.local/tech-angels/go-example”. Let’s create a Dockerfile for this project:
FROM docker:5000/go:1.2 ADD . /go/src/gitlab.local/tech-angels/go-example # Fetch deps WORKDIR /go/src/gitlab.local/tech-angels/go-example RUN go get # Allow to mount the current version in the container VOLUME /go/src/gitlab.local/tech-angels/go-example
With the common Makefile:
all: build build: docker build -no-cache -rm -t docker:5000/go-example .
We now have a full project environment, ready to compile and test, without installing anything else than Docker.
And now, configure the CI Server
We are using Gitlab-CI to test our projects, but the following will work with any CI server out there.
docker pull docker:5000/go-example docker run -t -i -rm -v `pwd`:/go/src/gitlab.local/tech-angels/go-example docker:5000/go-example go test -cover
Our CI will just start a container, run the tests, and get an exit code from the go command.
We didn’t add the save / restore deps step in this very simple example. It’s trivial to add it, and you’ll need a test script inside the container for that.
Also, you probably realize now how simple it is to test with different go versions!