Vim, RVM, VirtualBox and SSH: my current ruby on rails development environment

As a former Linux + C developer, I've spent most of my early days with a very simple (yet powerful) set of tool: a terminal, vim and make.
My development cycle was quite simple:

Make your changes:
$> vim file.c

Compile it
$> make

Run and test your program by hand
$> ./my-program

Debug it
$> gdb ./my-program

That was all I needed for many years.

And so came along the magic of ruby and rails and things started getting a little bit more complex than that. Also I moved away from Linux as a desktop environment and started using OSX, which just added more chaos to the development setup.
Truth is, although OSX is unix based, posix, etc, etc and you CAN run the same stuff as you do on Linux, things are always simpler with linux in terms of open source development.
You have better support, better packaging, etc.

I've tried and used for a while my whole rails stack straight into my OSX box. But after some time you have to upgrade things, install dependencies, then you get trouble with ports, brew, whatever you are using, your environment starts getting a mess and you wish you were using Make and C again in 2001.

I've tried TextMate for while. It's kind of nice, but I really missed Vim.

So, enough history, here's how I develop for rails currently:

Isolate everything using VirtualBox


First I isolate everything inside a virtual machine under VirtualBox. VirtualBox is free and very simple to use.
It also can create snapshots of your vm (which I recommend), so you can rollback your environment if things get screwed (it does sometimes).

It's much quicker to just rollback a vm than reinstall the whole stack again.
For the brave and advanced user, you can even automate the bootstrap of you vm using Vagrant.
It's nice if you several dependencies and you want to share it with a team.

As OS preference I use Ubuntu. I have never tried anything else other than slackware in the past, but I've been quite happy with it so I don't see a point in changing.

So what I do is create a virtual box, get the latest ubuntu server and install into it.

Connect to your environment


You have basically two options with your vm: either you use it as a full graphical system or you connect to it using SSH. I prefer the latter because I don't lose my actual desktop interface (OSX).
For using the VM over SSH, I recommend setting the Network settings to use NAT and configure proper port forwarding (more on it below).

I usually setup:

  • localhost 2280 to port 22 on the vm, and
  • localhost 3080 to port 3000 on the vm.

I don't like bridge network because you can have your vm's ip changing over time which just make things worse.

So just open a terminal and connect to localhost on port 2280 (which will forward to port 22 in the vm).
If you are using something like OSX, I recommend you also create aliases for ssh to speed things up.

I usually put into my ˜/.ssh/config file:

host dev
user myusername
hostname localhost
port 2280

With this I can more easily type:
  $> ssh dev
Instead of
  $> ssh myusername@localhost -p 8022

Using X from inside SSH

Surprisingly, you can run X applications from inside your SSH connection using something called X11 forwarding.

Doing this is very simple, given you have X on your host (which you do if you are running OSX).
Simply connect to you box passing -X to ssh:
  $> ssh dev -X

The -X option tells ssh to open a tunnel and forward X11 messages to your host.
After doing that you are able to run you favorite X application from inside your VM straight into your desktop.

For example, after connection to the vm, type:
  $> gvim

This will bring gvim in your desktop. Sweet, isn't it?

Editing your files: GVim, not Vim

As you might have realized from the previous section, I actually use gvim when connected to SSH instead of VIM. Gvim has some advantages over Vim, like better mouse integration, for example (not that you are gonna want to use the mouse...).

Vim is highly customizable and there are some plugins you can use to make your life easier (I highly recommend installing then and taking the time to learn how to use it).
Take a look at the plugins from this guy: Tim Pope

So I like to use these:
  • pathogen: install it first. allows better management of vim plugins
  • most other tpope plugins, take a look and pick the ones you like
  • NerdTree: adds a file browser like capability to vim
  • Comman-t: TextMate like command-t to search for filenames.
I'm not going to teach how to use vim here. You can always type "how do I..." on google :)

Managing ruby with RVM

When using ruby, you probably want a specific version, or the latest version, or the production's box version, etc. Whatever version it is, it's usually NOT the version your system's packaging system gives you.
So the standard here is to use RVM
Nice thing about it is you can switch between multiple version and run everything inside your local user (not need to mess with your global system files).

Forward you SSH keys to your vm

Another nice trick with SSH is to use agent forwarding. You need an SSH key if you are connecting to a git server, for example, like github. So in general you want to have a single key in your desktop instead of creating an additional key inside the virtual machine.
Worse, you don't really want copy your identity key from your desktop to your VM.
So here is the trick, you can either:
  $> ssh dev -A
or add to your ˜/.ssh/config

ForwardAgent yes

So now you can connect to your VM and use git normally as you would locally. Your keys are forwarded so you don't need to copy it.

Development cycle using TDD, RSPec and Guard

So for the final step, here is where you spend most of your time: writing code.
I came across this gem called Guard. Its principle is quite simple: you keep it running and it monitors your files. As soon as it detects changes it runs your automated tests automatically for you so you have instant feedback of your code.
It supports rspec, cucumber, test:unit, among others and uses a rule system to determine which tests to run for each file that you change. Quite sweet.

So for the most time what I do is have gvim opened where I edit my files and write tests at the same time.
On a separate screen I have guard running where I keep watching the output to get feedback from my code.
This way I can literally use gvim only, without the need to make the "code, compile, test" cycle. It all goes down to a single step: write code, which at the end is what matters.

Final Thoughts

So to summarize, I develop for rails using Vim over SSH. It's quite old school but I find it very powerful.
I'm still optimizing this setup and trying to make it more efficient and the tools work better for me.
Of course I'm open for hints and improvements!

Hope you enjoy :)


1 comment:

  1. All i can say is : There is no school like old school !!!!! Thanks a lot for writing this post.

    ReplyDelete