Rails App

Phase Eleven - Deploying Your Application

One of the more complicated tasks in the lifecycle of an application is getting it on a server for people to look at. This can be a rather complex task, but we will use a service that is specifically designed to make this a relatively painless task.

The Heroku service is a platform that allows you to run web applications written in most of the popular web languages.

Setup

For this, we need to follow the Heroku Quickstart Guide’s instructions to install the Heroku toolbelt and login from the command line.

Prepping Scriba

Heroku works with git, which makes deploying a snap. However, there are a few things we need to do to make this work better.

Ignore Files

We need to tell git to ignore certain files. Specifically files that are updated though the server (e.g. the log files and image uploads). For this we need to edit a special file .gitignore. You can do this in an editor, or for fun, you can do it through the console. Remember what the echo command does? What about »?

$ echo "public/uploads" >> .gitignore
$ echo "tmp" >> .gitignore
$ echo "longer" >> .gitignore
$ git commit -am "Ignore files not needed for deployment"

Open .gitignore in your text editor after all is said and done. Notice anything? Most of these files were probably already included in the .gitignore file that rails generated for you. This won’t cause any problems, but you might want to clean out the extra lines.

Database Configuration

We have been using a database system in our default Rails application called SQLite. However, Heroku uses a far more robust system called PostgreSQL. If we deployed our application as is, we’ll run in to problems since our application doesn’t know how to “talk” to a PostgreSQL server. We need to tell Rails about this dependency in our production environment by updating the Gemfile.

Find the line that reads gem 'sqlite3' and update it to look like this:

group :development do
  gem 'sqlite3'
end

group :production do
  gem 'pg'
end

This tells our application to use one database in development and another in production (when it is running up on Heroku). These sorts of nuances can be very useful when you want to test and run different things while debugging and developing than on your live site.

12 Factor

Heroku requires applications to adhere to Twelve-Factor App principals. To make this easier for you, there’s a gem that will configure your application in production to adhere to these principals. All we need to do is add the rails_12factor gem to the production environment in the Gemfile. Update the :production group as follows.

group :production do
  gem 'pg'
  gem 'rails_12factor'
end

Now you can update the dependencies, but we can run only what we need in development with the following:

$ bundle install --without production

Now, add and commit the updated Gemfile and Gemfile.lock.

Web Server

By default, you web application runs through a web server named Webrick. This is a great server in a development environment, but is really horrible as a server in production environments. Heroku enourages you to use Unicorn. We don’t need to do this right now, but if you want to continue developing this application, this is something you will want to do.

Deploying Your App

To create a new application on heroku (assuming you installed the heroku toolbelt) with the heroku create command.

$ heroku create
Creating shielded-temple-5358... done, stack is cedar
http://shielded-temple-5358.herokuapp.com/ | git@heroku.com:shielded-temple-5358.git
Git remote heroku added

In my case, my app is named shielded-temple-5358. Part of this setup is that we have a new git remote named heroku. To see what remotes you have for your project, remember that you can type git remote -v.

Now we can push the master branch to this remote.

$ git push heroku master
Initializing repository, done.
Counting objects: 277, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (257/257), done.
Writing objects: 100% (277/277), 46.21 KiB | 0 bytes/s, done.
Total 277 (delta 119), reused 0 (delta 0)

-----> Ruby app detected
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using 1.6.3
       Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       Fetching gem metadata from https://rubygems.org/..........
       Fetching additional metadata from https://rubygems.org/..
       ...
       Bundle completed (23.42s)
       Cleaning up the bundler cache.
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       I, [2014-08-01T13:26:28.837146 #1055]  INFO -- : Writing /tmp/build_773a12b8-29a6-4f50-b9bf-532c14eba8dc/public/assets/application-c23ffbdd24d84fb51367f46fe4f80265.js
       I, [2014-08-01T13:26:28.902130 #1055]  INFO -- : Writing /tmp/build_773a12b8-29a6-4f50-b9bf-532c14eba8dc/public/assets/application-8d28fbaea5f9f776a348eec2dacde8c6.css
       Asset precompilation completed (7.42s)
       Cleaning assets
       Running: rake assets:clean

###### WARNING:
       You have not declared a Ruby version in your Gemfile.
       To set your Ruby version add this line to your Gemfile:
       ruby '2.0.0'
       # See https://devcenter.heroku.com/articles/ruby-versions for more information.

###### WARNING:
       No Procfile detected, using the default web server (webrick)
       https://devcenter.heroku.com/articles/ruby-default-web-server

-----> Discovering process types
       Procfile declares types -> (none)
       Default types for Ruby  -> console, rake, web, worker

-----> Compressing... done, 21.5MB
-----> Launching... done, v6
       http://shielded-temple-5358.herokuapp.com/ deployed to Heroku

To git@heroku.com:shielded-temple-5358.git
 * [new branch]      master -> master

You’ll know you’re done when you see the “Launching…” text in the console.

Database Migration

We also need to migrate the database. We do this by telling heroku to run the rake db:migrate task.

$ heroku run rake db:migrate
Running `rake db:migrate` attached to terminal... up, run.4973
== 20140627192049 CreateTranscriptions: migrating =============================
-- create_table(:transcriptions)
   -> 0.0786s
== 20140627192049 CreateTranscriptions: migrated (0.0788s) ====================

== 20140719205623 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0809s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0398s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0283s
== 20140719205623 DeviseCreateUsers: migrated (0.1497s) =======================

== 20140730172249 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0820s
== 20140730172249 CreateComments: migrated (0.0822s) ==========================

Check it out

The simplest way to get to your application is from the terminal and typing heroku open. Is it working?

Plugins

A few things to note, Heroku is a cloud platform with no persistant storage. If you read the Heroku notes, you’ll see the following:

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

You can do an experiment here; go to your application and upload a new transcription image. Then, in the console, run heroku restart to restart your application. If you go back to the web page, your image should no longer be visible.

A common approach to this is to use a service like Amazon S3 (Simple Storage Service) or Rackspace CloudFiles. This is relatively inexpensive (generally less than $0.10/GB) and provides you a method to save your media uploads.

We wont’ get in to this here either, but again, if you want to go further with this application, here are some useful links for implementing this:

Summary

You now have an application you can share with your friends and family. And, without getting into a “back in my day” talk, this is one of the simplest ways to deploy an application, but it’s not the only way. Similar services to heroku (if you don’t have your own IT staff) include: