Integrity CI on Passenger 2.2.2 with Ruby Enterprise Edition on Ubuntu 8.04

I just spent a few hours trying to get this configuration sorted out, so I thought I'd share my notes. My goal was to get Integrity running on Passenger with Ruby Enterprise Edition. However, I couldn't get the user Integrity/Apache was running as to use the proper PATH.

Whenever Integrity would try to build my project, I'd get an error about rake not being able to be found: sh: rake: not found

This totally threw me. I had added it to /etc/environment

PATH="/opt/ruby/bin:$PATH"

and so it was certainly on my PATH:

john@john-ci:~$ echo $PATH
/opt/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

I had also added it to /root/.bash_profile so that root would have it picked up:

john@john-ci:~$ sudo su -
root@john-ci:~# echo $PATH
/opt/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

So why wasn't Apache/Integrity picking it up? To seek this out, I opened up the Integrity source and edited /opt/ruby/lib/ruby/gems/1.8/gems/integrity-0.1.9.3/lib/integrity/project_builder.rb to output the values of whoami and $PATH to help me troubleshoot.

IO.popen("(echo `whoami` && echo $PATH && cd #{scm.working_directory} && $
          |output| build.output = output.read }

Doing this yielded the following output:

www-data
/usr/local/bin:/usr/bin:/bin

At this point, I wholly expected the PATH to not include /opt/ruby/bin, so this isn't a surprise. But why is this being set?

The Real Problem

The real issue here was that I was trying to set the PATH in scripts that only get run when a shell is entered. Since apache starts up as a system process, it is not started from a shell, and does not have a PATH associated with it. In fact, if you open up /etc/init.d/apache, you'll see on one of the first few lines that the PATH is distinctly set:

ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin"

This was precisely the PATH I was seeing when I hacked Integrity to output its PATH just prior to failing the Rake command. Now it's fairly obvious that I just need to add in /opt/ruby/bin to the front of that PATH, and Integrity will be able to execute all of my ruby/rubygem executables (most importantly rake).

Recap of Steps to Install

  1. Download and install REE
  2. Create a symlink for /opt/ruby so it's dead simple to upgrade when a new REE comes out: sudo ln -s /opt/ruby-enterprise-whatever-version-you-installed /opt/ruby
  3. edit /etc/environment to add /opt/ruby/bin to your shell PATH : PATH=/opt/ruby/bin:$PATH
  4. edit ~/.bash_profile to alias sudo so that sudo can inherit your environment : alias sudo='sudo env PATH=$PATH'
  5. Reload your environment to pick up the new PATH: source /etc/environment && source ~/.bash_profile
  6. Install Passenger: sudo gem install passenger && passenger-install-apache2-module
  7. Install Integrity Gem: sudo gem install integrity
  8. Install Integrity Home: sudo integrity install --passenger ~www-data/integrity
  9. Install do_sqlite3 Gem: sudo gem install do_sqlite3
  10. Prepare Integrity Database: cd ~www-data/integrity && sudo integrity migrate_db config.yml
  11. Grant ownership of all integrity files to www-data: sudo chown -R www-data:www-data ~www-data/integrity
  12. Create Apache config for Integrity: sudo nano -w /etc/apache2/sites-available/integrity:
<VirtualHost *>
  ServerName ci.yourdomain.com
  DocumentRoot /var/www/integrity/public
</VirtualHost>
  1. Enable the site: sudo ln -s /etc/apache2/sites-available/integrity /etc/apache2/sites-enabled/002-integrity
  2. Edit /etc/init.d/apache2 and add /opt/ruby/bin to the PATH as described above: ENV="env -i LANG=C PATH=/opt/ruby/bin:/usr/local/bin:/usr/bin:/bin"
  3. Restart Apache: sudo /etc/init.d/apache2 restart
  4. Navigate to http://ci.yourdomain.com/ and start adding projects.

Boy, that was a mouthful. Please let me know if you've also been successful, and if there are any other steps you take to set up Integrity with REE and Passenger.