Rails on Maui

Programming in Paradise

Rocking With Tmux, Tmuxinator, Guard, Zeus, and iTerm2 for Rails Development

What’s the most effective way to:

  1. Start several different processes for Rails, such as Zeus, Rails server, rspec, resque, and the scheduler.
  2. Have the output for each process in a separate tab.
  3. Not have the process pause when you scroll the output, as happens in tmux.

Here’s a short demo of using tmuxinator to get a project running in several iterm2 tabs:

Why Guard?

I use Guard for:

  1. Automatically running rspec tests based on changes in either tests or source files. Together with Zeus, I haven’t found a faster way to get immediate feedback from tests. Pro tip: Learn how to use :focus with your specs to configure exactly what tests to have guard run.
  2. Automatically restarting the server when needed. For example, if you change gems or routes, you need to restart the server.

While I love running Guard with Zeus, Spring is the default in Rails 4.1, so I’ll probably give that a try in the near future.

Why Tmuxinator and Tmux?

Tmuxinator is awesome for configuring the layout of several processes.

Here’s a sample tmuxinator file.

When I run the command

1
mux my_project

And then I see the following. This is way easier than opening up tabs in iTerm2 and running commands every time.

The main problem with this setup is that if you scroll a window backwards (using the tmux keyboard bindings), and you don’t un-scroll, then the process pauses, such as the Rails server. That’s super annoying. Often I’m running specs, and I want to scroll back to see a stack trace, but that prevents the continuation of the test run! Here’s a short discussion of the issue.

iTerm2 with tmux to the Rescue!

iTerm2 has wonderful tmux integration. Here’s the steps I take:

  1. Be sure have the latest versions of tmux, tmuxinator and iTerm2. As of this article, I’m using: tmux: 1.9a, tmuxinator: 0.6.7, iTerm2: Build 1.0.0.20140112.
  2. Configure your Tmux to open tabs rather than windows. This is key to getting the iTerm2 version to look like your original tmux session.

Once you have the setup done, this is how I start my iTerm2-tmuxinator session:

  1. Start tmuxinator with command mux my_project
  2. Hit ctrl-a, d to detach the tmux process.
  3. Run command =tmux -CC attach”

Here’s how it will look:

If you want to kill the session, you can run this command:

1
tmux kill-session -t my_project

However, that sometimes does not kill all the processes. I often use these two zsh scripts to ensure that everything is killed. It’s super important to kill Zeus before running db migrations or gem updates.

1
2
3
4
5
6
7
8
9
10
11
pgr() {
  for x in rails phantomjs zeus; do
    pgrep -fl $x;
  done
}

pgk() {
  for x in rails phantomjs zeus; do
    pkill -fl $x;
  done
}

Why Tmuxinator/tmux and not Foreman?

I use Foreman with Heroku and for running my rails server in production mode. However, I prefer having different tabs provide console output for each of the processes, rather than having all the console output blended together as Foreman does. I’m also not sure if Foreman integrates with Guard.