It's time for us to deploy our first application to Heroku. If you've deployed applications to Heroku before, this will be a good review. If this is your first time, you'll be learning the common steps taken to deploy any application to Heroku.
The creators of Heroku have experience in deploying and scaling countless web applications. They've seen it all. From their experiences, they have created a methodology known as the Twelve-Factor app. The Twelve-Factor app is a set of 12 rules that will guide us to build an application that is easy to deploy, easy to maintain, and, most importantly, easy to scale on a cloud platform. No matter what language or framework we are using to build our application, these twelve rules will apply.
Note
Visit http://12factor.net/ to learn more about the Twelve-Factor app.
Ruby on Rails follows most of the twelve rules out of the box. This makes it a good place to start when learning how to deploy to Heroku, because it requires minor configuration changes. In this recipe, we will be deploying Refinery, a popular open source Ruby on Rails Content Management System (CMS).
To run this application locally, we need to have Ruby Version 2.1.3 installed by performing the following steps:
One of the easiest ways to install Ruby is to use Ruby Version Manager (RVM). We can find the latest installation instructions for RVM at http://rvm.io/rvm/install.
Once RVM is installed, we can run the following command in a terminal to install Ruby 2.1.3:
$ rvm install 2.1.3
We'll use Bundler to manage and install our applications' dependencies. Let's make sure we have the latest version installed by running the following command:
$ gem install bundler
This application also uses a Postgres database. We'll be using Postgres frequently throughout the book; if we do not have it installed on our machine, now is a good time to get it set up:
For OS X, the easiest way to install Postgres is via the Postgres app available at http://postgresapp.com/
For Windows and Linux, see the Postgres download page at http://www.postgresql.org/download/
We'll set up and deploy our application from the command line. Let's open a terminal to get started using the following steps:
First, we need to download the source code for our sample app from GitHub. We can do this using
git clone
:$ git clone https://github.com/mscoutermarsh/refinery_heroku.git
Now, let's navigate to our new directory and create a new Heroku app. Creating a new app will also add a new
heroku
remote to our Git repository. This remote is where we will be soon pushing our code for deployment:$ cd refinery_heroku $ heroku apps:create Creating cryptic-chamber-6830... done, stack is cedar http://cryptic-chamber-6830.herokuapp.com/ | [email protected]:cryptic-chamber-6830.git Git remote heroku added
We will tell Heroku how to run our app with a Procfile. In the root directory of our new app, we'll create a new Procfile to tell Heroku how to start up our web service. Let's create the file using the
touch
command:$ touch Procfile
Now, let's open our new Procfile and add the following line. This will tell Heroku how to start our web server process:
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
We can now commit these changes to Git:
$ git add Procfile $ git commit -m 'Adding Procfile for Heroku'
Next, let's add the Twelve-Factor app gem to our application. It will automatically configure our application's logging and assets to work correctly with Heroku. Let's open our application's Gemfile and add the following line:
gem 'rails_12factor', group: :production
As we've added a new gem, we'll want to run
bundle install
to update our application's dependencies:$ bundle install
Note
To learn more about Bundler, take a look at http://bundler.io/.
We'll need to make another commit with our latest changes:
$ git commit -am 'Adding 12 factor gem'
This application uses a Postgres database. We'll need to add Postgres to our Heroku application. Let's do this now:
$ heroku addons:add heroku-postgresql:dev ----> Adding heroku-postgresql:dev to cryptic-chamber-6830... done, v3 (free) Attached as HEROKU_POSTGRESQL_GOLD_URL Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pgbackups:restore.
Note
The Heroku CLI knows which application to add the database to, because our current Git repository has a
heroku
remote that points to this Heroku application. If we wanted to run the command for a different application, we could append--app application_name
to the end of the command. This will be very useful once we have multiple applications deployed to Heroku.Ruby on Rails uses an environment variable to connect to the database. We can set this now using the
promote
command. This will assign our new database's credentials to theDATABASE_URL
environment variable.We'll use the database name given to us in the previous command as the argument in this command:
$ heroku pg:promote HEROKU_POSTGRESQL_GOLD -----> Promoting HEROKU_POSTGRESQL_GOLD to DATABASE_URL... done
We're now ready to push our code to Heroku. We'll do this using Git's
push
command. We'll need to specify theheroku
remote and our master Git branch:$ git push heroku master Initializing repository, done. Counting objects: 92, done. Delta compression using up to 4 threads. Compressing objects: 100% (79/79), done. Writing objects: 100% (92/92), 35.83 KiB | 0 bytes/s, done. Total 92 (delta 11), reused 0 (delta 0) … -----> Discovering process types Procfile declares types -> web Default types for Ruby -> console, rake, worker -----> Compressing... done, 37.1MB -----> Launching... done, v9 http://cryptic-chamber-6830.herokuapp.com/ deployed to Heroku To [email protected]:cryptic-chamber-6830.git 46345bc..583680c master -> master
Now that our application's code is on Heroku, we need to completely set up our database by running migrations and seeding it with some data:
$ heroku run rake db:migrate $ heroku run rake db:seed
Our app is now ready to use! We can quickly launch a browser and view it with the
open
command:$ heroku open
Once our application is open, let's go to Refinery in the browser to register a user and start using the Refinery CMS.
In deploying this Rails application, we were introduced to a couple of Heroku concepts that we will be using when deploying any application to Heroku. Let's dig into them a little deeper now.
Each Heroku application should have a special file in its root directory that defines each of the processes required to run the application. This file is known as a Procfile. If we forget to include a Procfile, Heroku will try to guess what process we want to run. It's better for us if we're explicit about exactly what Heroku should do.
In this recipe, we created a Procfile that told Heroku what command to run to start our web server. The Procfile can be used for more than just web processes. In applications that also have processes running in the background, the Procfile is where we'd define how to start them. On Heroku, we can only have one web process. This is the only process that Heroku will direct web traffic to. Other processes will not be able to receive web traffic. If we find a use case where we need more than one type of web process running, this is a good indicator that we should have multiple Heroku applications.
When we ran the db:promote
command, we added an environment variable to our application to store our database's credentials. This is good practice and follows the conventions of the Twelve-Factor app. We should never store credentials for any service in our Git repository. It makes our credentials less secure, because they are then accessible to anyone who works on our code. It also makes them more difficult to change, because any change will require another deploy. Credentials tend to be very environment specific; having them as part of a Heroku application rather than our code base makes our application more portable. With all this being said, the key is to remember that when building any application for deployment on Heroku, we should build the ability to load credentials from an environment variable into our code.
When we pushed our Git repository to Heroku, the slug compilation process began. Heroku takes our Git repository, detects the language and the framework used, and begins to build a slug in our application. A Heroku slug is a copy of our application that is ready to be deployed on Heroku's servers at a moment's notice. For a Rails application, this means that all of the application's Gems have been installed, and its assets have been compiled. Heroku also removes any unnecessary files from our Git repository to make the slug as lightweight as possible. We can think of it as a snapshot of our production-ready application. Heroku hangs on to each slug it creates, making it easy for us to roll back to a previous slug if needed.
Find out more about the Refinery CMS at http://refinerycms.com/
Find out more about Foreman and the Procfile at http://ddollar.github.io/foreman/
To learn more about deploying Ruby applications on Heroku, take a look at Chapter 7, Optimizing Ruby Server Performance on Heroku