Sunday, February 2, 2014

ruby2.0.0 (RVM) and Heroku on Ubuntu 13.10

Ruby2.0.0 (RVM) Rails and Heroku on Ubuntu 13.10

With my recently updated (K)Ubuntu 13.10 and a project we delayed until vacations, came up the decision of use Rails 4 to continue the development.

This is a web application we started as a Symfony2 but, as we're on vacations with the summer and all that, i decided make it fun, also we have like one month to go back.

What i'm going to do now is describe how i set up my dev environment for a base Web Application in heroku with Rails 4 and Ruby 2.0.0

Also, i used RVM onto a separate user to avoid break things with other code laying around on my laptop.

1. New User account  and RVM

As i mentioned before, i did create a new user account, this user account, just in case, was created into the sudo group, i came handy later :)

$ sudo adduser rubydev
...
$ sudo adduser rubydev sudo


right after i logged into "rubydev" account and installed RVM.
(it might be necessary to install "git" and "curl" packages through apt-get if they are not already installed)

$ \curl -L https://get.rvm.io | bash -s stable

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   184  100   184    0     0    125      0  0:00:01  0:00:01 --:--:--   125
100 20511  100 20511    0     0   7169      0  0:00:02  0:00:02 --:--:-- 59798
Downloading https://github.com/wayneeseguin/rvm/archive/stable.tar.gz

Installing RVM to /home/rubydev/.rvm/                                                                                                                                                           
    Adding rvm PATH line to /home/rubydev/.profile /home/rubydev/.bashrc /home/rubydev/.zshrc.
    Adding rvm loading line to /home/rubydev/.bash_profile /home/rubydev/.zlogin.
Installation of RVM in /home/rubydev/.rvm/ is almost complete:

  * To start using RVM you need to run `source /home/rubydev/.rvm/scripts/rvm`
    in all your open shell windows, in rare cases you need to reopen all shell windows.

# rubydev,
#
#   Thank you for using RVM!
#   We sincerely hope that RVM helps to make your life easier and more enjoyable!!!
#
# ~Wayne, Michal & team.

In case of problems: http://rvm.io/help and https://twitter.com/rvm_io


Cool, now we got RVM, there should be some way that i don't know to make rvm command functional right after it's installed. but i just logged out and logged back in.

Gemsets

With RVM you can set up different gemset files and later choose wich gemset and ruby version use, we will get stick with the default gemset, because we just made and entire user just to test around Ruby2.0.0 and Rails. (On my normal/daily user account i got Ruby1.9.3).

Anyways, if you prefer to create a separate gemset you should type:

$ rvm use ruby-2.0.0-p353@heroku-expedit --create

(my gemset would be called heroku-expedit, name yours whatever you want)

With that you will create a gemset using ruby-2.0.0, and use the recently created gemset with your project.

For more on gemsets: http://rvm.io/gemsets

2. Installing Ruby and Rails

Now with "rvm list known" we can see the possible ruby versions we can install. (a lot).

$ rvm list known

# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.7[-p374]
[ruby-]1.9.1[-p431]
[ruby-]1.9.2[-p320]
[ruby-]1.9.3[-p484]
[ruby-]2.0.0-p195
[ruby-]2.0.0[-p353]
[ruby-]2.1.0
[ruby-]2.1.0-head
ruby-head

The list goes on with JRuby, Rubinius, MacRuby and others interpreters and versions of them, but we want just one of the MRI versions. we will take "ruby-2.0.0-p352", so:

$ rvm install ruby-2.0.0-p352

Checking requirements for ubuntu.
Installing requirements for ubuntu.
Updating systemrubydev password required for 'apt-get --quiet --yes update': 
...........
Installing required packages: gawk, libreadline6-dev, libyaml-dev, sqlite3, libgdbm-dev, libncurses5-dev, bison, libffi-dev.......
Requirements installation successful.
Installing Ruby from source to: /home/rubydev/.rvm/rubies/ruby-2.0.0-p353, this may take a while depending on your cpu(s)...


In the line where password was required, we tanks that we were sudoers, because RVM tried to install some libs into our system.

After a while we will get this message and our command line back:

Install of ruby-2.0.0-p353 - #complete
$ _



Now we can just install Rails from gem:

$ gem install rails
Fetching: atomic-1.1.14.gem (100%)
Building native extensions.  This could take a while...
Successfully installed atomic-1.1.14
Fetching: thread_safe-0.1.3.gem (100%)
Successfully installed thread_safe-0.1.3
Fetching: tzinfo-0.3.38.gem (100%)
Successfully installed tzinfo-0.3.38
Fetching: multi_json-1.8.4.gem (100%)
Successfully installed multi_json-1.8.4
Fetching: i18n-0.6.9.gem (100%)
Successfully installed i18n-0.6.9
Fetching: activesupport-4.0.2.gem (100%)
Successfully installed activesupport-4.0.2
Fetching: erubis-2.7.0.gem (100%)
Successfully installed erubis-2.7.0
Fetching: rack-1.5.2.gem (100%)
...
Fetching: bundler-1.6.0.pre.1.gem (100%)
Successfully installed bundler-1.6.0.pre.1
...
Fetching: rails-4.0.2.gem (100%)
Successfully installed rails-4.0.2
...
14 gems installed

$ _



Now we got installed Rails, Bundler, Activerecord, and all the usual. Still we need some other gems to get this working with Heroku.


3. Heroku gems and stuff

Next steps, more or less, follow this guide provided by Heroku Dev Center: devcenter.heroku.com - getting started with rails4

Mandatory gems

This two gems are necessary to get your application working with Heroku, "pg", and "rails_12factor".

"pg" gem is needed because Heroku will work with postgreSQL instead of SQLite3, because SQLite is not a production grade database engine, and Heroku provides postgreSQL databases as a service.

"rails_12factor" is needed to supply integration functions between Heroku and Rails, such as logging and static assets serving.

It's posible that compiling "pg" gem fails if "libpq-dev"  is not installed in our system (why would be installed anyways?), these are the headers and static libs for the PostgreSQL Library.

So, install the libpq5 libraries first:

$ sudo aptitude install libpq-dev

And then the gems:

$ gem install pg rails_12factor


Heroku toolbelt

As is written in their home page, this will install some tools neded to deploy your application to Heroku platform.

This will install on your computer the Heroku Client, a command line tool to manage your apps. Foreman, and Git. Foreman is an optional tool used to run your apps locally.

More details here: toolbelt.heroku.com

Now we will install the tools with:

$ sudo wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh

Not shure if sudo is necessary because the script will ask you for your sudo password anyways.

The tools will get installed through apt automatically.

Now login into heroku with the CLI tool will help us manage our apps:

$ heroku login Enter your Heroku credentials. Email: mycoolname@mail.com Password (typing will be hidden): Could not find an existing public key. Would you like to generate one? [Yn] Y Generating new SSH public key. Uploading SSH public key /home/rubydev/.ssh/id_rsa.pub... done Authentication successful. $ _

And that's it. nex we will try an Example app.


4. Example App

From now we will assume you have installed a postgreSQL server to test/dump/whatever you database.

First we will create a test application:

$ rails new test_site --database=postgresql

We wait a while, in my case 'bundle install' keeps me waiting for a few minutes, so i went to the kitchen for a cup of tea in the meantime.

After the app is created we enter its directory with
$ cd test_site/

Now we need to create a root page as Rails 4 will no longer offer a static index page in production:

$ rails generate controller welcome index


And change the routing in our app so welcome#index is shown when we visit it, editing the routes file.

config/routes.rb
root 'welcome#index'


Preparing app to Heroku

Now we need to edit the database config file to remove the username from the database parameters, as we don't have any user named 'test_site'. (At least i don't).

config/database.yml
development:
  adapter: postgresql
  encoding: unicode
  database: test_site_development
  pool: 5
  #username: test_site
  password:

test:
  adapter: postgresql
  encoding: unicode
  database: test_site_development
  pool: 5
  #username: test_site
  password:

production:

  adapter: postgresql
  encoding: unicode
  database: test_site_development
  pool: 5
  #username: test_site
  password:


To make a little test, i will create the databases and run Rails as web server:

$ rake db:create
$ rake db:migrate
$ rails s


Now in some browser y typed:  http://localhost:3000

This way we will take a look and check if everything goes fine.



I got this basic app, you can modify the welcome index view to something fancy if you want.



5. Deploying to Heroku


Final tuning

First thing we need to do before deploying to heroku is edit the Gemfile and add one of the bundles we talked a while ago, that are necessary to Heroku integration with Rails.

We will  take to birds in one shoot editing the Ruby version also at the end of the Gemfile.

./Gemfile
gem 'rails_12factor', group: :production
...
ruby "2.0.0"

then we need to run bundle install to generate a new 'Gemfile.lock':

$ bundle install


Upload

At this point, every thing would run just great. so we will upload it to Heroku, wich internally relies on Git for this task.

So, into the Rails project directory we will create a local repo and commit our files.

$ git init
$ git add .
$ git commit -m "init"


Then with the Heroku command line tool (assuming we are logged in) we will create the remote repo to upload our app:
$ heroku create

And push the changes to Heroku with git:
$ git push heroku master


Now we have deployed our code to heroku. :)


6. Config on heroku side

Heroku at the time this is written gives you computer time to run your application on a development context for free for one month, every month. Then you can pay and scale up on databases number, speed on a production environment and leave your application running there.

Their measurement unit are the 'Dyno-hours'. you are allowed to run your app at 1x dyno-hour, for long as 750 dyno-hours per month, which is enough to keep your app running for one month free (on a development context of course).

It's better explained here: devcenter heroku - billing

Once our code is on heroku if it needs a database we will need to create one on heroku side, to run any command on heroku we use 'heroku run'. As example we will create our databases.

$ heroku run rake db:migrate
Running `rake db:migrate` attached to terminal... up, run.2971

We can see our app and database on the dashboard on heroku site. yet, i won't upload images from the Heroku site. you can go and have a look at your own.

Now we can check if our app is running, and at how many dynos, we type:
$ heroku ps
=== web (1X): `bin/rails server -p $PORT -e $RAILS_ENV`
web.1: up 2014/02/02 02:00:33 (~ 40m ago)




We can see how our app is running on one 1x dyno, we can set it to 0, or maybe set it to 1 1x-dyno if it wasn't running because we already turned it down.
$ heroku ps:scale web=1
Scaling dynos... done, now running web at 1:1X.



How if we open our test site?

we can try this, or open our app from the dashboard in your heroku account. Heroku will provide us a url that can be changed later when/if we scale up to a production environment.

$ heroku open

Mine looks like this:



There are more detailed instructions on the Heroku devcenter articles, especially this one i already mention at the start of this entry: devcenter Heroku - Getting started with Rails 4



...And that's it. Now i will start coding this thing!



* Heroku is a registered mark (?) or belongs to Heroku, Inc. US. i'm not affiliated or associated in any way, and any coincidence on texts, descriptions, etc. might be product of the previous reading of their articles and are not intentional. As consequence, are not in any way an attempt of any kind of copyright infringement.