We have Jenkins deployed with the following stack:
- Ubuntu 12.04 LTS provided by DigitalOcean ($5 USD/month)
- Nginx configured for HTTPS, acting as a reverse proxy for Jenkins
- Jenkins installed via the
- Various Jenkins plugins, including the Bitbucket OAuth plugin for restricting access
- Rbenv for installing and managing Ruby environments needed by our various Jenkins jobs
1. Install Qt libraries
As we had already encountered on our development machines, the capybara-webkit gem won’t even install unless we have the necessary Qt libraries.
$ gem install capybara-webkit Fetching: capybara-webkit-1.0.0.gem (100%) Building native extensions. This could take a while... ERROR: Error installing capybara-webkit: ERROR: Failed to build gem native extension. /home/deployer/.rbenv/versions/2.0.0-p247/bin/ruby extconf.rb Command 'qmake -spec linux-g++' not available
Installing these libraries involves a different set of commands for each operating system, and is documented on the capybara-webkit GitHub wiki. For our Ubuntu 12.04 LTS setup, here’s what we had to do:
# as root aptitude -y install libicu48 libqtwebkit-dev
2. Install xvfb and use it to invoke rspec
The tricker problem is that WebKit requires a display.
bundle exec rake spec ... webkit_server: cannot connect to X server
This isn’t an issue when running specs on our Mac development environments, but on a headless Linux continuous integration server, a workaround is needed.
This workaround is a utility called Xvfb, or “X virtual framebuffer”.
# as root aptitude -y install xvfb
To use it, we had to change how we invoke rspec by wrapping it with the
xvfb-run command. Here’s the solution we added to each of our Jenkins jobs:
if type xvfb-run; then DISPLAY=localhost:1.0 xvfb-run bundle exec rake spec else bundle exec rake spec fi
Now our capybara-webkit specs run great on our CI server.
More best practices for Rails and Jenkins
If you’re setting up Jenkins for the first time, or looking for ways to improve your existing Rails CI approach, check out these additional resources:
- jenkins-ci.sh is the bash script that Jenkins invokes to test each of our Rails projects. It ensures the required Ruby is installed, creates and migrates the database as necessary, runs Rspec via xvfb, and generates a Brakeman security vulnerability report.
- vagrant-jenkins is a recipe for provisioning a DigitalOcean VPS and fully installing and configuring a Jenkins CI server with Rbenv, PostgreSQL, Nginx, and all the techniques described in this post. Fork the project and give it a shot!