Build and Deploy Semi Static Sites with Ruby on Rails 4, Bootstrap, and Heroku

By March 26, 2015 Programming One Comment
I've had several clients who want semi-static sites with room to grow into a fully dynamic app if business is good. This tutorial post documents the process I've used recently from zero to deployment. This tutorial assumes you have an account setup at github and heroku, and that you have ruby and rails both installed on your local machine. First, check and set your ruby version, I use rbenv to manage my ruby versions. $ ruby -v ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux] Good, 2.2.0 is what I want to use for the current Rails release. Let's make sure Bundler is installed, we'll need that. $ bundler -v Bundler version 1.7.13 Looks good. Now let's check and make sure we have Rails 4.2 installed. $ rails -v Rails 4.2.0 Perfect. Let's create our new rails app, here its called "place_setting". $ rails new place_setting After that finishes, pop open the Gemfile and let's add some gems. Since Rails now ships with sass, we'll start with adding 'bootstrap-sass' to include the twitter bootstrap framework. Then we'll add the gem 'high_voltage', for handling static pages. This isn't necessary, you can easily roll this yourself, but I like the standard method high_voltage brings to the table. I also like to add the 'better_errors' and 'binding_of_caller' gems to the development and test environments. Never use those in production. For our webserver, I'll use thin, so add that here too. I'll also have to make a Procfile to tell thin to start in production, later. To make Heroku happy, I'll also add the gem "rails_12factor" to the production group only. Here's what I added. gem 'bootstrap-sass', '~> 3.3.4' gem 'high_voltage', '~> 2.2.1' group :production do gem "rails_12factor" end group :development, :test do gem 'better_errors' gem 'binding_of_caller' end Now let's remove the cruft we don't need from the Gemfile. Delete the following gems: sqlite3, turbolinks, jbuilder, sdoc. We aren't starting with a database, so we don't need sqlite3. We can always add postgres or whatever later. My Gemfile now looks like this: source 'https://rubygems.org' ruby '2.2.0' gem 'rails', '4.2.0' gem 'bootstrap-sass', '~> 3.3.4' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0' gem 'jquery-rails' gem 'high_voltage', '~> 2.2.1' group :development, :production do gem 'thin', :group => 'production' end group :production do gem "rails_12factor" end group :development, :test do gem 'byebug' gem 'web-console', '~> 2.0' gem 'spring' gem 'better_errors' gem 'binding_of_caller' end Let's bundle to install those gems. $ bundle OK, we are set to go. First, lets strip out the extra cruft we don't need from rails yet. No database needed, so no ActiveRecord needed. Open up config/application.rb and replace the call to require 'rails/all' with: require 'rails' require 'action_controller/railtie' Also, while you've got config/application.rb open, go ahead comment out the reference to active_record # Do not swallow errors in after_commit/after_rollback callbacks. # config.active_record.raise_in_transactional_callbacks = true Comment out ALL the references to ActionMailer in the various config/environments/ files since we may want it back later. Comment out this in config/environments/development.rb # config.action_mailer.raise_delivery_errors = false # Raise an error on page load if there are pending migrations. # config.active_record.migration_error = :page_load comment out this in config/environments/test.rb # config.action_mailer.delivery_method = :test comment out this in config/environments/production.rb # config.active_record.dump_schema_after_migration = false # config.action_mailer.raise_delivery_errors = false Time to remove other Rails cruft we don't need: $ rm -rf config/database.yml public/index.html $ rm -rf app/{helpers,mailers,models} test/ doc/ db/ We removed turbolinks from our Gemfile, so we need to remove all our references to it. Open up app/views/layouts/application.html.erb and remove the calls to turbolinks. Before: <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> After: <%= stylesheet_link_tag 'application', media: 'all' %> <%= javascript_include_tag 'application' %> Delete the call to turbolinks in the app/assets/javascripts/application.js file. Remove: //= require turbolinks Next, rename app/assets/stylesheets/application.css to app/assets/stylesheets/application.scss and delete everything inside. We need to remove all the //= require and //= require_tree statements from the file. Instead, use @import to import Sass files. Do not use //= require in Sass or your other stylesheets will not be able to access the Bootstrap mixins or variables. Read more at the "bootstrap-sass" docs. Add the following import commands. @import "bootstrap-sprockets"; @import "bootstrap"; Require Bootstrap Javascripts in app/assets/javascripts/application.js. My application.js file now now contians: //= require jquery //= require bootstrap-sprockets //= require jquery_ujs //= require_tree . Bootstrap is now added to the asset pipeline and ready for use. Let’s add a homepage. Since this is a single-page app/site, let's just make a home page and open it up with Sublime. $ mkdir app/views/pages $ subl app/views/pages/home.html.erb Inside app/views/pages/home.html.erb add the following html. This will also test to see if our bootstrap is working. <h2>h2. Bootstrap heading <small>Secondary text</small></h2> <button type="button" class="btn btn-primary">Left</button> We'll need a route to access the page, so in your config/routes.rb add the route to the high_voltage page. root :to => 'high_voltage/pages#show', :id => 'home' Let's fire up a rails server and we should see our home page. $ rails s Nice! Everything looks good. Let's get this under source control. $ git init $ git add -A $ git commit -m "Initial commit" At github, create a new repo in your account. This is aptly named place_setting. Back in your terminal, push this up to github. $ git remote add origin https://github.com/yourgithubusername/place_setting.git $ git push -u origin master I'd also like to include the Bootswatch theme "Flatly" in here, so let's add that. I haven't had any luck using the bootswatch-rails gem, but it adds more than we need anyway. Let's grab the theme files we need. $ cd app/assets/stylesheets $ mkdir flatly $ cd flatly $ curl -O https://bootswatch.com/flatly/_variables.scss $ curl -O https://bootswatch.com/flatly/_bootswatch.scss I'm also using the scrolling-nav template from Start Bootstrap. I only need pieces of this since I'm using gems to bring in bootstrap. The files we'll need to download and add to our project are: startbootstrap-scrolling-nav/css/scrolling-nav.css startbootstrap-scrolling-nav/js/jquery.easing.min.js startbootstrap-scrolling-nav/js/scrolling-nav.js Copy those files in to your rails app into these places. copy startbootstrap-scrolling-nav/css/scrolling-nav.css to app/assets/stylesheets/scrolling-nav.scss copy startbootstrap-scrolling-nav/js/jquery.easing.min.js to app/assets/javascripts/jquery.easing.min.js copy startbootstrap-scrolling-nav/js/scrolling-nav.js to app/assets/javascripts/scrolling-nav.js Create a custom.scss to hold your own custom styles. Make sure you are in your rails project root first. $ cd ../../../.. $ touch app/assets/stylesheets/custom.scss Now add the new bootswatch theme and nav template styles in to the asset pipeline, in app/assets/stylesheets/application.scss. And also add the reference to your own custom.scss file. /* Import styles */ @import "bootstrap-sprockets"; @import "flatly/variables"; @import "bootstrap"; @import "flatly/bootswatch"; @import "bootstrap/variables"; @import "bootstrap/mixins"; @import "scrolling-nav"; @import "custom"; Let's incorporate the scrolling-nav template as well. It gets broken up into the app/views/layouts/application.rb and app/views/pages/home.html.erb files, and it's up on github if you want to grab them.

app/views/layouts/application.rb - app/views/layouts/application.html.erb

app/views/pages/home.html.erb - app/views/pages/home.html.erb

Since we are going to deploy to heroku, let's create our Procfile from thin at the rails root we mentioned at the very beginning. Here's a one liner: $ echo "web: bundle exec thin start -p \$PORT" > Procfile Optional: If you want to precompile assets before deploying, run $ RAILS_ENV=production bundle exec rake assets:precompile Let's fire up a rails server and we should see our site. $ rails s Everything looks good. Now we are going to deploy to heroku, so first make sure you have the Heroku toolbelt installed locally. You check to make sure it installed like this: $ heroku version heroku-toolbelt/3.20.0 (x86_64-linux) ruby/2.2.0 Cool, time to deploy. The heroku create command will automagically create your heroku app instance and also sets your git remote url for you. $ git add -A $ git commit -m "Prep to deploy" $ git push $ heroku create $ git push heroku master Optional: To hook up your custom domain: $ heroku domains:add www.yourdomainname.com At your host, edit the DNS ZONE file. We need a "CNAME(Alias)" and the 'Host' should be www and 'Points to' should be your Heroku address (example supermoo-bil-3411.herokuapp.com). TTL is different based on your host and settings. Add New Relic add-on to your site: $ heroku addons:add newrelic Follow the instructions to configure New Relic monitoring. You will end up downloading a newrelic.yml file, that you'll add to your rails app at config/new_relic.yml Open the NewRelic Panel by running $ heroku addons:open newrelic Agree to their contract, and then click on New Relic APM. Next, choose Ruby for the web agent to install. Follow their steps, they are self explanatory. We already added the "newrelic_npm" gem in the beginning, so don't do that again. Download the newrelic.yml file and it to your rails app root. Let's push our changes back up and redeploy: $ git add -A $ git commit -m "Add new_relic" $ git push $ git push heroku master Now access the New Relic APM again, $ heroku addons:open newrelic

And click on your application. Now, in the left hand panel under Reports, choose "Availability". In the field for "Url to monitor", enter http://www.yourdomainname.com

This will ping your site frequently to keep heroku from cycling down your dyno.

Visit http://www.yourdomainname.com now and check out your shiny place setting.

To see a live demo of this app, check it out on heroku at https://secret-waters-7370.herokuapp.com/

Best of luck to you. Enjoy your place setting.

Join the discussion One Comment

Leave a Reply

Social Links