In previous post i scratched the topic of managing and sharing your development environment. By using Vagrant to manage virtual machines and one of provision tools you can setup configurable environment. Furthermore you can setup your production machine to match this configuration. Lets roll up our sleeves and set it up.
First step is to prepare Vagrant configuration so execute
vagrant init command. This will generate sample
Vagrantfile with lots of helpfull comments, for now you can delete them to keep configuration clean and tidy. As a box name use
Now each time when you execute
vagrant up vagrant will search for box with this name. If doesn’t find it in imported boxes will search his online catalog and download it for you. You can also safely
vagrant destroy if needed (for sure we will use it later).
Vagrant has built in functionality to provision box while creating it. What it means is that you can execute custom scripts that will install and configure software for you. There are some tools that support this kind of operations which i mentioned in previous post. For now i will use chef solo provisioner.
In short Chef provisioning uses sets of instructions (called recipes) to setup virtual machine. Recipes can be configured with attributes use templates and be separated in several files. All of those can be combined into Cookbook. There are many configured cookbooks and can be found on Supermarket. Some of them are fine tuned and can be found on [GitHub][github-site].
To easily use and manage existing cookbooks install librarian-chef ruby gem
gem install librarian-chef and initialize it
librarian-chef init in folder with
Vagrantfile. Chef configuration file
Cheffile will contain commented out examples delete them to keep it clean and tidy.
You can group and tune cookbooks into roles. Most often they are grouped into functional groups, for example if your environment is split into 2 VMs (database server and application server) you will end up with 2 roles: database and application. Let’s create one role to keep Chef configuration out of
roles and inside of it ruby script
base.rb. Role scripts needs to have name so add
name 'base'. We will add more to it when we add some cookbooks.
Now we need to tell Vagrant where is should search for cookbooks and roles. Also add this role to actual vagrant box.
Now lets add first cookbook to install RVM and configure it to install newest ruby version (2.2.0). Add
cookbook 'rvm', '~> 0.9.2' to
Cheffile and execute
librarian-chef install. Cookbook for rvm and all it’s dependencies will be places in
cookbooks folder which will be searched by Vagrant provisioning.
Next step is to adjust
base role to install rvm and ruby. To install rvm system-wide accordingly to README we need to add
recipe[rvm::system] recipe to run list.
Now lets adjust attributes to install ruby 2.2.0, use it as a default and gem
bundler. Also to give user
vagrant ability to install gems we need to add it to
Now lets execute
vagrant reload to refresh synchronized folders and
vagrant provision to make use of installed cookbooks and set role. It can take a few minutes to complete. When finished you can
vagrant ssh into machine and check version
ruby -v and installation folder of ruby
Every time when you execute
vagrant destroy and
vagrant up you will end up with VM configure exactly same way.
As a database backend PostgreSQL is used frequently if application is either self hosted on VPS or on Heroku. In second case PostgreSQL if forced by hosting provider. So having it configured in development enviornment is helpful. Let’s add required cookbook and adjust our role.
Don’t forget to execute
librarian-chef install to actually install new cookbook.
If we are using standalone version of chef (other option is that chef recipies are managed by dedicated server) there is a need to setup password for
postgres user. Another catch is that to allow
postgres user to be authenticated by password. That is why we set
pg_hba variables which are reflected in configuration with same name. I took value of this attribute from original recipe and changed authentication method from
Last things to setup in vagrant is to expose port that is used by rails to host machine. Current folder is mounted in
/vagrant path by default. If project is kept in different folder than folder with Vagrantfile you need to explicit setup it to be mounted in VM. Let’s do this and we will be able to create new project!
All you need now is to
vagrant up then
vagrant ssh and
cd /path/to/project/in/vm to be in your development sandbox. Your default machine won’t be cluttered with many per project configurations. You can easily experiment with different setups and event split your application into many dedicated servers. Most important it is OS agnostic, easily replicable, configuration consistent and can be shared with everyone.
Please be warned to keep password for production database safe and secure. This Chef configuration is written for development environment not production.