Hybrid Windows/Ubuntu VM Rails development environment
My development machine is a PC, running Windows 7. This has never been an issue for any of my projects, whether I was using C++, C#, PHP/MySql, or NodeJS… until I started using Rails. While it was relatively straightforward to to get the “hello world” working, the pain really started when adding gems. Very quickly, I was spending more time getting the infrastructure right, and less time coding the actual product. Also, when time came to deploy to Heroku, a whole new set of problem arose. Without going into too many details, rails on windows wasn’t working for me. That’s when I started looking evaluating some alternatives:
- Use Ubuntu on my PC: Too painful to transition. I really like Windows 7, and am really productive using it. The cost of transition from using a Ubuntu vs. Win7 is too high.
- Run OS X on my PC: I tried, but unfortunately had no connectivity as I couldn’t find drivers for my wireless card.
- Run OS X in a VM: Running OS X VM from my Win 7 host worked, even if it was not trivial to setup. I did end up using it for a month or so, but the performance hit from running in a VM was really affecting productivity (IDE felt slow), mainly due to the lack of hardware accelerated graphics.
- Buy a MacBook Pro: Frankly, it’s too expansive for me. If you have an extra one, I’ll gladly accept it
Some of the options above might work for some, but wasn’t good enough for me. After much thinking, it became clear I needed a better solution which takes the best from both worlds: Develop on Windows, but run Rails from Unix. That’s when I came up with a “hybrid” environment which accomplishes the following:
- All your rails files are stored in Windows (e.g. C:/Rails/MyProject)
- Edit all your files from Windows, using your favorite IDE
- View your website from Windows, using your favorite browser (e.g. http://rails:3000/)
- Setup your Rails environment (e.g. Start server, Rails CLI, install gems, etc..) from Windows, through a SSH channel towards your Ubuntu VM
- Run your Rails server from an Ubuntu VM, using VirtualBox
Really, all you need to do is to turn on the VM, and while everything runs in Unix, you control everything from Windows Such a setup is really useful beyond Rails. Here is a step by step tutorial for creating this hybrid Windows/Linux development environment:
Setup your Virtual Machine
- Download and install VirtualBox for free
- Download an Ubunutu ISO
- From VirtualBox, create a new VM. I called mine “UbuntuVM”, and suggest you to do the same to make it easier to follow the steps.
- Edit the virtual machine settings, to mount the downloaded Ubuntu ISO
- Boot the VM, and follow all the steps to install Ubuntu
Configure VM network
- Shutdown the VM, and edit network settings as displayed in the screenshots below. The first adapter (attached to NAT) will ensure you VM gets inernet connectivity from your host machine (Windows 7). The second adapter (host-only adapter) will be used for the VM to have its own static IP address relative to the host machine (Windows 7). This is particularly important if you are using a laptop which connects through different networks.
- Boot the VM, and open a terminal window.
- Find out your VM’s current IP, by typing from the terminal: sudo ifconfig eth1
The IP to look for is the “inet addr”, which is 192.168.56.101 in the example below.
- Make that IP static (rather than auto assigned by DHCP) by editing the file /etc/network/interfaces. If you want to use nano for editing files, from the terminal, type: sudo nano /etc/network/interfaces
Modify the file similarly to the screenshot below (but put the IP you found on the previous step), then save changes by pressing: “Ctrl + X” followed by “Y” then “[Enter]” (nano commands for saving changes)
- Finally, save changes a reboot the vm. At this point, you VM should always have a static IP, which is reachable from your host machine. You can verify that from your command prompt by pinging the machine:
If that whole process felt complicated, worry not. That was actually the hardest part
- From the VM terminal, install openssh by typing: sudo apt-get install openssh-server
- From your host Machine (Windows 7), you should now be able to SSH into your VM. I personally use Putty to SSH into my VM. Your machine hostname is the one we made static from the previous steps.
- At this point, you should be able from windows to install on your VM ruby, rails, and its dependencies. There are a lot of tutorials covering installing rails on Ubuntu, so I will not cover that. But make sure you’re able to create a new rails app, and run the server before moving on in the tutorial. Also, because your IP is static, the server should be accessible from your host machine (windows 7) already at this point. This is pretty cool if you ask me
Shared folders between Windows/VM
- Now, we want to be able to edit files from windows. Create a folder on windows which you want to share with the VM (and put a text file in it for testing, e.g. “hello.txt”). In my exemple I use D:\Projects\UbuntuVM.
- Turn off the VM, and edit “Shared Folders” settings as follows:
- Boot the VM, and install guests additions. A command prompt will open and install all sorts of “additions”. These are required for accessing the shared folder from the guest VM. Reboot the machine afterwards.
- Now comes the time to create a folder on the VM, and mount it to the folder we created in Windows. Perform the steps in the screenshot below to do so.
- This is now working, but next time the VM reboots, you will need to remount the shared folder. That sucks. So let’s add an entry to /rc/rc.local to make sure the shared folder is automatically mounted during startup:
- Restart the machine, and notice the shared folders are now linked. At this point, we have a fully operational hybrid setup with fulfills all of our objective established at the beggining of the article:
(Optional) Setup hosts
If you don’t want to remember or type your VM’s IP, then you can edit your hosts files to give it a more human readable name. To do so, open notepad as an administrator, and edit your hosts file (C:\Windows\System32\drivers\etc\hosts).
Voila, no more steps. I realize setting up the environment for the first time can be a bit time consuming and confusing at moments, but it’s a well worth investment. I included a lot of screenshots in hope of making that process simpler to follow, and hope it will benefit you. Let me know if you decide to try it, or if you run into any complications in the process. Happy coding!