<-- home

Run ruby services on OS X with chruby & launchd

I’ve been running some ruby services on OS X machines lately and ran into a few roadblocks. Hopefully this will help someone!

Preparing the server

Getting a fresh ruby installed with the excellent chruby and ruby-install is no problem.

You’ll need to have enabled chruby system-wide in order for it to be loaded during deployment.

Otherwise deployment is fairly straightforward. I got along just fine with the sensible defaults provided by capistrano and capistrano-chruby.

Now your fresh code and dependencies are all ready to go. This is where it gets interesting.

Intro to launchd

On a Linux OS you have a number of options: runit, upstart, systemd etc. But to manage services on OS X you really want to be using launchd.

At first it seem a bit counterintuitive, but there are some tools and abstractions that make it a little easier to manage.

  • LaunchControl provides a GUI for managing and creating launchd services. It’s especially useful when creating a new service from scratch.
  • lunchy is a wrapper for the not-intuitive launchctl CLI provided by OS X.

A lot of launchd itself is outside of the scope of this post. For a good reference check out the launchd Tutorial.

Running your ruby code

The key to running a chruby-installed ruby in a launchd job definition is the chruby-exec command.

For example, on my system I have ruby-2.4.0 installed and I want to run a rake task called roll_call. I could run the following command.

/usr/local/bin/chruby-exec ruby-2.4.0 -- bundle exec rake roll_call

Which translates to the following in a job definition:


However, running bundle exec won’t work from outside of a ruby project directory. So set the working directory to the currently deployed project.


This job will now successfully run but in the development environment. Easily fixed by setting an environment variable.