Installing VirtualBox

In order to run a consistent development environment across multiple machines it is necessary to use a virtual machine as the app’s server. This is just a operating system sandboxed within your own operating system (Ubuntu running inside of OSX in my case). Luckily VirtualBox provide a free solution for running virtual machines. You can download the latest version for your operating system here:

https://www.virtualbox.org/wiki/Downloads

Follow the provided instructions for installing and then continue below.

Installing Vagrant

Vagrant is a stellar piece of tech that allows for easy to setup, manage and copy interaction instructions for VirtualBox virtual machine. Basically by using Vagrant to setup your virtual machine you can make duplicates of said environment at the click of a button and then share it across all your computers and servers or with your colleagues and co-contributors. You will need to be familiar with using the command line to feel comfortable with vagrant. In any case even if this is all new to you simply copy the instructions I have provided word for word and everything should work as planned.

Now it’s time to download the correct version of Vagrant for your computer (OSX for me as I am doing this on a mac) and install it:

http://www.vagrantup.com/downloads.html

Once Vagrant has successfully installed it’s time to start setting up the development environment.

Setting Up Ubuntu

The team at Vagrant has kindly provided a few preconfigured Ubuntu images for use with Vagrant. You can find a full list here:

https://vagrantcloud.com/boxes/search

Select the one you would like to use from the list and make a note of it’s name (eg ‘ubuntu/trusty64’ or ‘hashicorp/precise64’).

Next, in the terminal, go to the folder where you wish to build your Rails app (for me it’s a folder called ‘Sites’ where I store all the files and assets of the apps that I work on) and type (be sure to replace hashicorp/precise32 with whatever box you chose from the list of available boxes):

#### Terminal

$ vagrant init hashicorp/precise32

Once you have hit enter you will see that a Vagrantfile was created in the folder inside which you typed the command in the terminal. Next we need to make sure that your app will be accessible on the localhost forwarding port 3000 as is the norm with Rails apps:

Open the Vagrantfile in a text editor such as Sublime and insert the following at line 23:

config.vm.network "forwarded_port", guest: 3000, host: 3000

You will notice that there is another commented out line around line 23 that contains similar information but forwards to another port. You can safely remove this line from the Vagrantfile . Once you have made the alterations save the file and exit the text editor.

Now it’s time to launch the virtual machine for the first time. Simply go to the terminal and type the following command:

#### Terminal

$ vagrant up

The first time you run vagrant up it will look for the operating system image that you have created the Vagrantfile for and try launch the desired virtual machine. As you have not installed the virtual machine operating system yet it will then initiate the download and installation of the operating system first. In my case it will download and install Ubuntu 12.04 "Precise Pangolin" as my virtual machine operating system.

Let the download and installation proceed. Now would be a good time to make yourself a coffee or even have a bite to eat. Depending on your internet speed this process could take some time.

Working inside the virtual machine

Ok so your download is finished and the virtual machine is installed and up and running. In order to enter the virtual machine you can simply SSH in with the following command:

Terminal

$ vagrant ssh

This command will enter you into the virtual machine as the user vagrant. This is very important to know for later when we setup the PostgreSQL database as we will use the vagrant user with no password to connect to the database from our Rails app.

Synced Folders between host OS and Virtual Machine OS

Once you have this setup you can work between the host OS and the virtual machine OS using the predesignated synced folder. The synced folder is the folder where the Vagrantfile is located (the same folder where your Rails app will reside). This is great as it means you can edit code in your host OS (OSX for me) and it will be readily accessible to be interpreted in your virtual machine. To access the synced folder inside the vagrant ssh session simply type the following in the ssh session terminal:

Terminal

$ cd /vagrant

*NOTE: Unless otherwise stated the rest of the Terminal commands are always inside the SSH session that is logged into your virtual machine. This will install or otherwise manipulate the operating system in your virtual machine, leaving your host OS untouched. *

Installing Git

As you will be working in a team it is most likely you will be using Git as a distributed revision control system (and even if you aren't working in a team you should still be using Git or something similar). You will need to install this on the virtual machine. Inside the already running SSH session in the terminal type the following:

Terminal

$ sudo apt-get $ updatesudo apt-get install git

Respond Yes or ‘Y’ to any prompts and that’s it, you should be good to go with Git.

Installing PostgreSQL

First let’s setup the language and encoding defaults for the system which Postgres will use as it’s default setting too.

Terminal

$ sudo /usr/sbin/update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8

Next let’s install PostgreSQL:

Terminal

$ sudo apt-get install postgresql libpq-dev

Once Postgres has successfully installed we will create a new database instance. Again within the SSH session:

Terminal

$ sudo mkdir -p /usr/local/pgsql/datasudo $ chown postgres:postgres /usr/local/pgsql/datasudo su $ postgres/usr/lib/postgresql/9.1/bin/initdb -D $ /usr/local/pgsql/data

Now we have to create a admin user for the database. We will call this user vagrant because as mentioned previously it will simplify much of the connection issues between your Rails app and Postgres. The user called vagrant will not need to provide the Rails app database.yml file a password in order to connect to the database.

Terminal

$ createuser vagrant

Type ‘Y’ and hit enter when asked “Shall the new role be a superuser?”

Now we can exit the su subshell to go back to the vagrant user SSH session:

Terminal

$ exit

Next we have to enter the Postgres console to add the user we just created as a verified user for the database instance and then quit out of Postgres console back to the vagrant user SSH session again.

Terminal

$ psql postgres=> ALTER ROLE vagrant CREATEDB postgres=> \q

Testing Postgres is setup correctly

Now, back in the vagrant ssh session prompt we can login to the Postgres console as the Postgres user to make the development and test databases for your app (please replace <yourappname> with the actual name of the app you will build once you have your development environment setup correctly):

Terminal

$ sudo su postgres $ psql postgres=# CREATE DATABASE <yourappname>_development postgres=# CREATE DATABASE <yourappname>_test postgres=# \list

The \list command will list all databases. You should see the two databases you just created in this list. You can now close terminal tab and open a new terminal window and log back into the virtual machine using vagrant ssh .

RVM

Also popular for managing Ruby versions is rbenv but we will go with RVM for now. If you know what you are doing and prefer to use rbenv or another options please feel free to deviate from the tutorial for this section and once you have finished jump back in at the next section ‘Installing Bundler’.

Before installing RVM we need to install curl to help us with fetching files. Then we can install RVM and load it into our current environment.

Terminal

$ sudo apt-get install curl\curl $ -sSL https://get.rvm.io | bash $ source /home/vagrant/.rvm/scripts/rvm

To test if RVM was successfully loaded type the following:

Terminal

$ which rvm/home/vagrant/.rvm/bin/rvm

Next we need to install all the requirements for building Ruby. Luckily with RVM this is trivial (without RVM it would take a long time):

Terminal

$ rvm requirements

Next we will install our desired version of Ruby (I’ll be going for Ruby 2.1 but you may want another one). We can see all the available versions of Ruby with this terminal command:

Terminal

$ rvm list known

To install Ruby 2.1 I used the following command (you can substitute in any number for the version your wish to install):

Terminal

$ rvm install 2.1

Wait awhile, while it compiles (tick tock tick tock… hmmm tea and biscuits) and then set the default Ruby version to the version you just installed:

Terminal

$ rvm use 2.1 --default

You can verify the changes were made by typing the following into terminal (both commands should give you easily readable output that confirms the Ruby version set as default):

Terminal

$ which ruby $ ruby -v

Installing Bundler

We are of course going to need Bundler installed in order to work with Rails gems.

Terminal

$ gem install bundler

Installing a JavaScript Runtime (NodeJS)

To able to use the Rails Asset Pipeline we will need a JavaScript runtime installed server side. For this we will use the much hyped NodeJS:

Terminal

$ sudo apt-get install nodejs

And that’s it. We can move onto Rails!

Rails Installation Options

First we can check for the current version of Rails. Rails 4.1.8 was the stable release when this was written.

If you install Rails now you will install it into the global gemset but it’s considered best practice to make a gemset just for the current stable release (so you can use different versions for different projects). After creating our gemset we will set it to the default gemset.

Terminal

$ rvm use ruby-2.1.5@rails4.1 --create $ rvm use ruby-2.1.5@rails4.1 --default

We’re then going to install most recent stable release of Rails:

Terminal

$ gem install rails $ rails -v

The rails -v command is to confirm that the correct version was installed.

If you need to get a specific version of rails you can use the following tags (just substitute in the correct version number) with the install command:

Terminal

$ gem install rails --version=2.1.1

Next we need to run bundle install to install missing dependencies.

Terminal

$ bundle install

Finally we can create our new rails app. To show that the folder sync / sharing is working we will do this in our host OS (OSX for me). Open a new terminal window in your host OS and navigate to the folder where the Vagrantfile was created. Now create a new rails app as you always would but make sure to add the database tag for Postgres.

Terminal

$ rails new <yourappname> --database=postgresql

After your new app has been generated you can replace the development and test contents of the config/database.yml file of the app with the following using your favourite text editor. Be sure to enter the names of the two databases you created earlier in the database fields.

development: adapter: postgresql database: <yourappname>_development encoding: utf8 pool: 5 timeout: 5000 test: adapter: postgresql database: <yourappname>_test encoding: utf8 pool: 5 timeout: 5000

If you left off the --database=postgresql when you created the app replace gem ‘sqlite’ with gem ‘pg’ in the app's gemfile.

Now run bundle update in the vagrant ssh terminal session to install missing dependencies.

Terminal

$ bundle update

You can now test the rails installation to make sure everything is working as it should. Still inside the vagrant ssh session, in the folder where the app resides:

Terminal

$ cd /vagrant $ cd <yourappname> $ rails server

Now navigate to the local host in your host OS browser (Chrome in OSX for me) and you should see the Rails welcome page.

http://localhost:3000/

Congratulations you've got a great shareable development setup and ready to go!..... buuuuut there is one more step you need to know

Cloning your new setup on another machine

To share the virtual machine you have just created you need to back it up by creating an image of it.

In the same folder as the Vagrantfile :

Terminal

$ vagrant package

This will shut down the VM and export an image named package.box (this will come in at about 700mb).

With this image you can now install it on any other machine that has Virtual Box and Vagrant installed.

On your new machine where you want to install the box all you have to do is (in the folder where the package.box is installed...probably a flash drive, Dropbox folder or wherever you stored the package.box file):

Terminal

$ vagrant box add package.box --name <yourappname>_box

Next navigate (in the terminal of the new machine still) to the directory where your app will live and type:

Terminal

$ vagrant init <yourappname>_box $ vagrant up