Run jenkins job in a docker image
Here's the instruction how to build a docker image using jenkins: RA_CI with Docker_08.25.2015.pdf . But it how to build/test you software inside a jenkins container?
Idea is to create a docker container from the image on each build request, execute the build inside this container and remove it after the execution.
Configure a docker runner
You need to have a docker server running and available from jenkins server. For that, run the docker with -H parameter:
docker -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
First parameter would make the docker listening on tcp port 2375, needed for remove machine. The second is to keep working locally without specifying -H for every docker command.
Don't forget to open the port in the firewall:
sudo iptables -I INPUT -p tcp -m tcp --dport 2375 -j ACCEPT
sudo service iptables save
Now test your docker server by executing from remote (jenkins) machine:
docker -H tcp://docker_server:2375 ps
Prepare the image for jenkins
The plugin puts some specific requirements for the docker image that to be used. I have an experience with gitlab-ci runner where it's needed to use CMD instead ENTRYPOINT. In jenkins it's actually required to have sshd up and running in the image and that goes against recommendations for docker images. Jenkins would run the image and then connect into it using ssh to execute the job. Another way to connect is "Docker JNLP launcher" which is experimental by the moment.
Here's the dockerfile for SCL6 that contains sshd configuration and inherits my original image:
FROM amerezhi/slc6-winccoa # inherit from original image MAINTAINER Alexey Merezhin <amerezhi@cern.ch> RUN yum install -y openssh-server && \ /usr/bin/ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C '' -N '' >&/dev/null && chmod 600 /etc/ssh/ssh_host_rsa_key && chmod 644 /etc/ssh/ssh_host_rsa_key.pub && /sbin/restorecon /etc/ssh/ssh_host_rsa_key.pub && \ /usr/bin/ssh-keygen -q -t rsa1 -f /etc/ssh/ssh_host_key -C '' -N '' >&/dev/null && chmod 600 /etc/ssh/ssh_host_key && chmod 644 /etc/ssh/ssh_host_key.pub && /sbin/restorecon /etc/ssh/ssh_host_key.pub && \ /usr/bin/ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C '' -N '' >&/dev/null && chmod 600 /etc/ssh/ssh_host_dsa_key && chmod 644 /etc/ssh/ssh_host_dsa_key.pub && /sbin/restorecon /etc/ssh/ssh_host_dsa_key.pub RUN adduser jenkins && echo "jenkins:jenkins" | chpasswd RUN sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config && \ sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
Add docker image as a jenkins node
1. First install Docker and Token Macro (??? docker plugin was failing without it ???) plugins in your jenkins server.
2. Add the docker server in jenkins system configuration - "Add a new cloud"/"Docker"
Specify the connection in "Docker URL" as "http://docker_server:2375". In the docker plugin help page they set "connection timeout" to 5 and "read timeout" to 15.
3. Click on "Add Docker Template" (aka Image) - here you define the image that would be run per build. Each template is associated by "label" and is an alternative to docker nodes.
Define "Docker Image" with the image you'd like to use and set the "label" field.
4. Now it's time to test it. Create a new freestyle jenkins job, enable "Restrict where this project can be run" and put the label of the docker template (from #3). Add a simple "execute shell" action with "echo hello world", save the job and click on build.
Now it first request a new container from the image, executes the bash and stop the container. Here's how it looks from docker server log:
$ tail -f /var/log/docker time="2016-02-16T13:52:37.180755217+01:00" level=info msg="GET /containers/json?all=0&size=0" time="2016-02-16T13:52:37.437466025+01:00" level=info msg="GET /containers/json?all=0&size=0" time="2016-02-16T13:52:37.448189275+01:00" level=info msg="GET /images/json?all=0" time="2016-02-16T13:52:37.760599927+01:00" level=info msg="POST /containers/create" time="2016-02-16T13:52:39.258787768+01:00" level=info msg="POST /containers/f31dd9335ae8992dacea1ce539f5cf53897125fe59d81fb8ee056b48cb070094/start" time="2016-02-16T13:52:39.543902200+01:00" level=info msg="GET /containers/f31dd9335ae8992dacea1ce539f5cf53897125fe59d81fb8ee056b48cb070094/json" time="2016-02-16T13:52:41.639100099+01:00" level=info msg="GET /version" time="2016-02-16T13:52:49.268243016+01:00" level=info msg="POST /containers/f31dd9335ae8992dacea1ce539f5cf53897125fe59d81fb8ee056b48cb070094/stop?t=10" time="2016-02-16T13:52:51.290620577+01:00" level=info msg="DELETE /containers/f31dd9335ae8992dacea1ce539f5cf53897125fe59d81fb8ee056b48cb070094?v=0&force=0"
Others
Docker plugin allows to see the list of running containers and images of the docker server. You can also stop a running container. Go to the "Manage Jenkins"/"Docker"/"you docker server name".
If you don't want to test this on production start your own jenkins instance using jenkinsci docker image
docker run -p 8080:8080 -p 50000:50000 jenkins
Another article on this subject: https://iww.inria.fr/tech-zone/using-docker-to-run-jenkins-jobs/