Now that you’ve built an application, let’s put it on the Web for everyone to see. Rails applications can be deployed in many ways. Rails runs on everything from simple shared hosting to dedicated servers to virtual servers in the cloud.
The cloud application platform known as Heroku is one of the easiest ways to deploy your application, and I cover it in this chapter. Heroku uses the Git version control system to deploy applications, so we need to talk about version control systems first.
A version control system (VCS) records changes to files over time so you can easily go back to a specific version later. The repository is the data structure, usually stored on a server, that holds a copy of the files in the VCS and a historical list of changes to those files. With a VCS, you can make changes to your source code knowing that you can always go back to the last working version.
Originally, version control systems were centralized. That is, the source code repository was stored on a single server. Developers could connect to that server and check out files to make changes to the code. But centralized systems also have a single point of failure. Examples of centralized version control systems include the Concurrent Version System (CVS) and Subversion.
The most popular type of version control system today is distributed. With a distributed version control system, each client stores a complete copy of the source code repository. That way, if a single client fails, everyone else can continue to work with no loss of data.
In a distributed system, a central server is still commonly used. Developers push their changes to this server and pull changes made by other developers. Popular distributed version control systems include Git and Mercurial. Because Heroku uses Git to deploy applications, I’ll focus on Git.
Git was originally developed by Linus Torvalds in 2005 for use with the Linux kernel. The word git is British slang for a despicable person. Torvalds once joked that he names all of his projects after himself.
Git quickly spread beyond the Linux community, and most Ruby projects now use Git, including Ruby on Rails. If you don’t already have Git, installation instructions can be found in Ruby, Rails, and Git.
Before you start using Git, set your name and email address. Open a terminal window and enter the following command to set your name:
$ git config --global user.name " Your Name"
The --global
flag tells Git to apply this change to your global
configuration. Without this flag, the change would only apply to the current repository.
Also, set your email address:
$ git config --global user.email " [email protected] "
Now every time you commit a change, your name and email address is included, making it easy to see who made which changes when working with a team.
Now you’re ready to create a repository for the blog. Move to your code/blog directory and enter this command:
$ git init
Initialized empty Git repository in /Users/tony/code/blog/.git/
This initializes an empty Git repository in the hidden .git subdirectory. Next, let’s add all of the application’s files to the repository:
$ git add .
The add
command accepts a filename or directory path and adds it
to Git’s staging area. Files in the staging area are ready to be committed to the
repository. The dot in the command represents the current directory. So after you run
this command, all files in the current directory and any subdirectories are ready to be
committed. When you commit, Git takes a snapshot of the current state of your project
and stores it in the repository.
Now commit all staged files to the repository:
➊ $ git commit -m "Initial commit" [master (root-commit) e393590] Initial commit 85 files changed, 1289 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile --snip-- create mode 100644 test/test_helper.rb create mode 100644 vendor/assets/javascripts/.keep create mode 100644 vendor/assets/stylesheets/.keep
Note that I specified the commit message "Initial commit"
with
the -m
flag ➊. If you leave off this flag, Git will open your
default editor so you can type a commit message. If you do not type a commit message,
the commit fails.
If you want to view the current repository’s commit history, enter the
git log
command. The list shows previous commits in order from
newest to oldest. Each entry includes who made the commit and when, along with the
commit message.
$ git log ➊ commit e3935901a2562bf8c04c480b3c5681c102985a4e Author: Your Name <[email protected]> Date: Wed Apr 2 16:41:24 2014 -0500 Initial commit
Each commit is represented by a unique 40-character hexadecimal hash ➊. These hashes can be abbreviated to the first seven characters—in this case, e393590—if you need to refer to this particular commit again.
As you work on a project using Git, follow this basic workflow:
Edit local files as needed.
Stage files to be committed with the git add
command.
Commit the changes to the repository with the git commit
command.
You can commit changes to Git as often as you like, but I find it helpful to commit changes related to a single simple feature or bug fix together. That way, all of the changes are tied to one commit, making it easier to revert and remove a feature if necessary. It’s also a good idea to commit any outstanding changes at the end of a working session.
Git contains many additional commands; enter git --help
to see
a list of those you’ll use most often. You’ve already seen the
init
, add
, commit
, and
log
commands, but here are a few more that you’ll find
particularly useful as you navigate Git.
The git status
command displays a list of changed and new
files:
$ git status
On branch master
nothing to commit, working directory clean
In this case, nothing has changed. Edit a file in your project,
README.rdoc, for example, and then enter the git
status
command again:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes...)
➊ modified: README.rdoc
no changes added to commit (use "git add" and/or "git commit -a")
The git status
command shows the current state of your working
directory and staging area. Here, it lists all files that have been staged for commit
and files with changes that have not been staged for commit ➊.
The git diff
command shows detailed changes to files:
$ git diff
diff --git a/README.rdoc b/README.rdoc
index dd4e97e..c7fabfa 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -1,4 +1,4 @@
➊ -== README
+== Blog
This README would normally document whatever steps are necessary to get the
application up and running.
Here, I changed the word README to
Blog ➊ on the first line of the file. Use this command
before git add
to see exactly what changes will be staged for
commit. You can also pass a filename to this command if you only care about changes to
a single file.
The git checkout
command can undo changes to a file:
➊ $ git checkout -- README.rdoc $ git status On branch master nothing to commit, working directory clean
Here, I’ve discarded the changes to the file
README.rdoc by using git checkout
followed
by two dashes and the filename ➊. This command does not produce any output.
Then I used git status
to confirm that the change had been
discarded.
The git clone
command makes a local copy of a remote
repository:
$ git clone url
The remote repository is represented by
<url>
. Git is a great tool for
collaboration and is used by many open-source projects. This command makes that
possible. Before you start working on an existing project, you
clone a copy of the repository to your computer.
You may have noticed that the git status
command includes the
phrase, “On branch master.” In Git, a branch is a
named set of changes. The default branch is called master. It
represents the main line of development. The changes I’ve made so far have all
been committed to the master branch.
If you’re working on a large feature that may take some time to complete, you can create a separate branch to store changes you’re working on without affecting the master branch. This way, you can work on your own branch without impacting the rest of your team. Once the new feature is complete, you’ll merge your new branch back into the master branch.
Use the git branch
command followed by a branch name of your
choice to create a new branch. In this example, I’ll call my branch
testing:
$ git branch testing
Enter the git branch
command without specifying a name to see a
list of the branches that currently exist in the repository:
$ git branch
* master
testing
The star shows the currently selected branch. I created a new branch, but
I’m still looking at the master branch. To switch to a different branch, use the
git checkout
command:
$ git checkout testing
Switched to branch 'testing'
Now I’m on the testing branch. Changes committed here will not affect the
master branch. Once you are finished making changes, checkout
the
master branch and merge your changes into it:
$ git checkout master Switched to branch 'master' $ git merge testing Already up-to-date.
All of the changes from the testing branch are now also in the master branch. You
can confirm this with the git log
command. Now that you’re
finished with the testing branch, add the -d
flag to the
git branch
command to delete it:
$ git branch -d testing
Deleted branch testing (was e393590).
You don’t have to delete branches after they have been merged, but doing so keeps the list of branches clean.
So far, all of our changes have been stored locally, but you should store an
additional copy of your repository on another server as a backup and to make it easier
for others to clone your repository. To do this, you need to set up a remote. A
remote is simply a nickname for another repository at a
specific URL. Use the git remote add
command to associate a
nickname with a URL:
git remote add name url
Once you have added a remote, use the git push
command to send
changes to the URL and the git pull
command to retrieve changes
made remotely. You’ll see a real-world example of this in the next
section.
Heroku is a cloud application platform for deploying web applications. This type of platform is sometimes referred to as a Platform as a Service (PaaS), meaning Heroku takes care of server configuration and management so you can focus on application development. The service also includes an extensive collection of add-ons. Getting started is free, but large applications requiring more processor resources and memory can get expensive.
After some initial setup, you can use a git push
command to deploy
your application and access it on the Web.
First, sign up for a free account at http://www.heroku.com. Remember the password you select; you’ll need it again to log in.
Next, install the Heroku Toolbelt if you haven’t already (see http://toolbelt.heroku.com/ for instructions). The Toolbelt is Heroku’s set of tools for deploying your application to its platform.
Now, open a terminal window, navigate to your blog directory, and log in to Heroku:
$ heroku login Enter your Heroku credentials. Email: [email protected] Password (typing will be hidden): Authentication successful.
This command prompts you for your email address and the password you created earlier, and then it checks your computer for an existing secure shell (SSH) public key. Your public key is one half of the public/private key pair used to authenticate over SSH. When you attempt to log on, your private key is used to make a cryptographic digital signature. Heroku then uses your public key to verify this digital signature and confirm your identity.
If you don’t already have a public key, press Y to create one when prompted. Your public key is automatically uploaded to Heroku after it is created. Heroku uses your public key for authentication so you don’t have to type your password every time you deploy your application.
Now that you’ve logged in to Heroku, you need to prepare your application for deployment.
No matter what kind of application you’re building, you need to install certain gems to interface with Heroku and deploy your application. In this section, we’ll look at the two gems you need to add to your application’s Gemfile.
Heroku’s servers use the PostgreSQL database server. Rather than install PostgreSQL locally, we used SQLite for development. You’ll need to ensure that the PostgreSQL gem, called simply pg, is installed in the production environment.
Heroku also requires the rails_12factor gem, which ensures that your application’s assets can be served by Heroku’s servers and that your application’s log files are sent to the correct place.
Open the file Gemfile in the root of your Rails application and
locate the line gem 'sqlite3'
. You’ll use the PostgreSQL gem in
production, but you still need the SQLite gem for development and testing, so update
this line by adding group: [:development, :test]
as shown
here:
gem 'sqlite3', group: [:development, :test]
This instructs the bundle
command to install this gem only in the
development and test environments.
Now you need to install the pg and rails_12factor gems just mentioned. You only need these gems in the production environment, so add these next lines below the line you just updated:
# gems required by Heroku gem 'pg', group: :production gem 'rails_12factor', group: :production
Once you’ve made these changes, save and close the
Gemfile. Because you’ve changed your application’s
Gemfile, run the bundle
command again to
update dependencies.
$ bin/bundle install --without production
Because you’re running this command locally, where you develop and test your
application, you don’t need to install production environment gems, so add the
--without production
flag. Bundler remembers flags passed to
bundle install
, so --without production
is
assumed every time you run the command from now on.
Finally, you need to add and commit these changes to your Git repository. Enter these commands to update Git with your changes:
$ git add . $ git commit -m "Update Gemfile for Heroku" [master 0338fc6] Update Gemfile for Heroku 2 files changed, 13 insertions(+), 1 deletion(-)
You could enter any message in place of Update Gemfile for Heroku, but commit messages are more helpful when they describe what you’ve changed.
Now, your account is set up, and your application is nearly ready to deploy. The last step is to create an application on Heroku:
$ heroku create
➊ Creating glacial-journey-3029... done, stack is cedar
http://glacial-journey-3029.herokuapp.com/ | git@he...
➋ Git remote heroku added
This command ➊ creates a new application on Heroku’s servers with a
randomly generated name. You could have specified a name after the
create
command, but the name must be unique. You can always change
the name later if you want. The create
command also ➋ sets up
a Git remote named heroku
for you automatically.
Everything is ready now, so you can finally deploy your application. Use the
git push
command to push the current state of your master branch to
Heroku:
$ git push heroku master Initializing repository, done. Counting objects: 102, done. Delta compression using up to 8 threads. --snip ------> Launching... done, v6 http://glacial-journey-3029.herokuapp.com/ deployed to Heroku To [email protected]:glacial-journey-3029.git * [new branch] master -> master
Heroku recognizes this git push
command and automatically detects
that a Ruby on Rails application is being deployed, installs the production gems
specified in your Gemfile, updates your application’s
database configuration, precompiles your application’s assets, and launches your
application.
When you deploy any application for the first time, you also need to run database
migrations to create the database tables needed by your application in Heroku’s
database server. Use the heroku run
command to execute the
rake db:migrate
command on Heroku’s server:
$ heroku run rake db:migrate Running `rake db:migrate` attached to terminal... up, run.1833 Migrating to CreatePosts (20140315004352) --snip--
If you make more database changes to your application, remember to commit the changes to the master branch in Git, push the master branch to Heroku, and run this command again.
Now you can open your web browser to the URL Heroku created for you earlier, or you can let Heroku handle that for you by entering this command:
$ heroku open
Your default web browser should open and load your blog application automatically.
Now that your application is set up on Heroku, you can deploy any time you want by committing changes to your Git repository and pushing the changes to Heroku.
Your blog is now safely stored in the Git distributed version control system. Changes
to your source code are being tracked and can be easily undone. You blog is also available
to the world via Heroku. Now you can deploy new features with a git
push
command.
This chapter marks the end of the first part of this book. We’ve covered the fundamentals of Ruby and Rails. Models represent your application’s data; views are the user interface for your application; and controllers are the glue that holds them together. You’ll use these concepts to build any application you want.
Looking at the application you built in Part I, you’ll find plenty of areas to improve. For example, anyone can edit or even delete posts on your blog. Also, what happens if you write thousands of posts? The index page will probably time out before it can display them all! You may not quite have the tools to fix those problems right now, but once you dive into Part II, that will change.
In the next part of this book, we’ll build a new social network application and cover advanced topics such as more complex data modeling, authentication, testing, security, performance optimizations, and debugging.
After learning these concepts, you’ll be able to solve these problems with the blog and build a variety of other applications.
18.219.228.88