Why Would You Do This?

I’m not going to go into an in-depth lecture about Agile Development or Extreme Programming, aka XP, but I will tell you that in my new company we’ve decided to embrace some of these practices; however, one of our team members lives in a state far far away (but luckily in the same time zone). This morning was my first opportunity to pair with him and so I setup an environment to allow us to share a terminal window quickly and easily with the following process.

Setup Dependencies

This process assumes that you already have a working development environment utilizing tools like Homebrew, RVM (or equivalent), and OS X / Linux.

1. Create Your Sandbox

Before your pair can access your system you’ll need to do a few things.

  1. Create a new user on your system, I went with pair. Unless you want to share your entire home folder with your office…
  2. Enable ssh authentication
  3. Ensure that tmux is installed (brew install tmux on OS X, see the Homebrew link earlier for details)
  4. Turn on Remote Login for the pair user only under Sharing in System Preferences on your Mac (if you’re on Linux I’m sure you can handle setting up ssh key-based auth).
  5. If you haven’t yet, make sure you have your Firewall enabled on your now publicly facing Mac.
  6. Have your pair send you their id_rsa.pub and add that key to your new pair user’s ~/.ssh/authorized_keys file.
  7. Remember to append your own id_rsa.pub file to the pair user’s ~/.ssh/authorized_keys file.
  8. Disable SSH Password Authentication on your Mac (or similar with Linux)
  9. Setup your development system to have a static IP on your router.
  10. Configure your router to forward port 22 to your development system’s static IP address.

2. Configure Your Shared Development Environment

Before these next steps you’ll want to login as your new pair user. This should be really easy for you locally, just run:

$ ssh pair@localhost

Now that you are the pair user you’ll want to configure a common development environment. Pairing can have it’s differences as every developer likes their own environment. Seeing as I was creating this on my own personal MacBook Air I decided to roll with what I use commonly for our defaults, and we’ll tweak them as we find things that drive my pairs insane (it’s bound to happen sooner or later). In light of this, I’ve created a Github project to make this easier for myself (and you) for future setup. We’ll start by cloning that repo and creating the appropriate symlinks.

$ git clone git://github.com/stevenhaddox/remote-pair.git dotfiles

3. Profit

That was easy wasn’t it? What, you’re not satisfied yet? Fine…

Real Configuration

After cloning the above repository you’ll need to peruse the files I have in there and pick and choose what fits your style. I’m certainly open to pull-requests to making this project better as a simple tool for remote pairing in general and am by no means an expert. I literally symlinked almost every file in the dotfiles folder into my pair user’s home folder. It’s kind of interesting to think of maintaining two separate dotfiles repos now, but it’s the right way to do it. My pair shouldn’t be forced to use my setup just because I’m lazy. But I don’t necessarily want my compromises on shared environments with my pair in my personal dotfiles either…

Once you’ve symlinked / copied / modified all the dotfiles that you want (I’d recommending making a fork rather than a clone actually that way you can customize it for yourself and your pairs), then you’ll just need to reload your bash_profile and be on your merry way to using tmux for blissful co-development:

$ source ~/.bash_profile

Setting Up Ruby

One awesome thing about local development in Ruby are tools like RVM / rbenv. I love RVM with a passion and use it on my persanal setups daily; however, my personal setups don’t translate into other users (unless you did a system wide RVM install instead of a local user, there are pros and cons to both options). If you’re like me and didn’t setup a system-wide RVM install then be sure to re-install RVM and the appropriate Rubies under the pair user account.

Get Back To Work

Alright, you’ve wasted to much time setting up this nice pristine environment. Get to work already. This is the easiest part. Both you and your pair can now ssh into your local development system as the pair user. Do so now with the following. The first person to login (probably the developer on the physical system with the pair user) should run:

$ tmux

Then have your pair run:

$ tmux at

This will put you both into a shared tmux window session and allow both of your keyboards to control the same code and user account. Face melted, I know. Alright, fine, you already knew about tmux because you’re cooler than I am. But I bet you didn’t know about Nyan Cat RSpec Formatter did you? Now who’s face is melted?

Extra Tips

Okay, so maybe just tip in the singular. The only other thing I want to do but haven’t yet, is to create a simple script that updates a subdomain on one of my primary domains via DNSimple’s API which will update the IP address for that domain every minute. This would allow your pair to access your development system easily by simply typing:

$ ssh pair@<subdomain>.<yourdomain>.<tld>

No more annoying IP addresses to lookup, just let your subdomain and auto-update script maintain it all for you :)

Also, I highly recommend putting your Google+ Hangout window on one screen with your pair looking directly at you and your tmux session on the other screen where you’re coding together. I can honestly say that my pairing experience today (all day) was just as amazing and awesome as any pairing session I’ve ever had in person.

Lastly, you’re probably wondering how you’re remote pair is supposed to view the site that you just developed together when you’re doing JS debugging, etc? Well there are several ways including forwaring another port from your router to the port your running your web application on, or both of you running the code locally and verbally discussing / screen sharing. My preferred option is to setup Showoff.io and just serve the port / Pow subdomain on via Showoff so the same site, code, and data is all being rendered in a publicly accessible URL that both you and your pair can look at simultaneously.

Happy hacking! Please provide feedback, war stories, experience, and pro tips you’ve experienced or come across in the comments! I’m more than open for improving this process!


Evan Light sent me a post on his blog from a few months ago that also discusses this exact same remote-pairing situation. He goes into a lot more depth and provides additional steps and some cool user setup/teardown scripts for OS X that are worth checking out to see if they’d be valuable to your workflow!