Deploying Spree using Heroku

I was having trouble running Spree on my shared host where I have multiple sites running. I saw that some had success deploying spree on heroku , so I thought I would give it a try. I was hoping to get an easy deployment process and also better responsiveness from the application. Also Heroku is free to start and you can pay to scale.

Here is a guide on how I got a fresh install of Spree running on Heroku rails hosting.

Setting the stage

I will assume ruby, rails, gems and git are all installed.

gem install spree
spree <app-name>
cd <app-name>
git init
git add .
git commit -m "initial commit"
heroku create

References: Heroku QuickStart | Spree Getting Started

I created a .gitignore file, it is not a requirement, to exclude certain local files that are created during development, such as sqlite3 or db files, log and tmp directories and even the product images.

Heroku gem manifest

Heroku has many gems already installed on their servers and is even more up to date than other hosts. However, Spree has many gem dependencies. To resolve this you create a gem manifest that is placed in the RAILS_ROOT, name the file .gems. I have gone ahead and copied my gem manifest that is necessary for Spree 0.9.2 gem to gist and is pasted below.

# .gems
activemerchant --version 1.4.1
activerecord-tableless --version '>= 0.1.0'
calendar_date_select --version 1.15
chronic --version '>= 0.2.3'
tlsmail --version 0.0.1
rspec --version '>= 1.2.9'
rspec-rails --version '>= 1.2.0'
will_paginate --version '>= 2.3.11'
authlogic --version '>= 2.0.11'
compass --version 0.8.17
stringex
whenever
spree --version 0.9.2

Based on the manifest I have created and the events over the summer of github no longer hosting gems we need to edit the environment.rb file. Three lines in question need the gem name and source changed to match the new gemcutter.org hosting.

#config/environment.rb
config.gem 'stringex', :lib => 'stringex', :source => "http://gemcutter.org"
config.gem 'whenever', :lib => false, :source => 'http://gemcutter.org'
config.gem 'will_paginate', :version => '~> 2.3.11', :lib => 'will_paginate', :source => 'http://gemcutter.org'

Heroku read only

Heroku is a read-only filesystem. This means that many new gems and other application features are limited. One such case is the use of SASS for stylesheets. In Spree the stylesheets are now compiled at runtime. Instead of looking at reworking Spree there is an easier option. The engineers at Heroku responded in the last few months with a plugin to allow SASS to work on Heroku. Simply add this to your spree application.

script/plugin install git://github.com/heroku/sass_on_heroku.git

The Heroku read only filesystem comes into play again. Spree uses the rails :cache feature for javascript and stylesheets. This is talked about some on the Spree-user google group. The simplest solution is to remove the :cache from the tags in the layouts.

Additionally Heroku allows commands such as heroku rake db:migrate to be run. This is very helpful but there are limitations. Heroku does not allow rake commands that require user input. This is covered in the Heroku Rake Docs. For Spree this is a problem because of the rake db:admin:create or rake db:bootstrap tasks used to setup the database. I came up with a solution to create a new task.

Both the :cache tag and the db:admin:create issues are addressed by a forked version of the extension spree-heroku. See the spree heroku extension code on my github repository. You can install it as an extension or take the ideas and add them to your site extension.

script/extension install git://github.com/tonkapark/spree_heroku.git

A admin_user.yml file is created in the extension config directory. You can leave it be or edit it for the different environments. It doesn’t matter because Spree allows users to change their email and passwords once logged in.

Spree Heroku extension disclosure

I want to disclose that I know my version of the heroku extension is incomplete for full production use. My version does not address the image storage issue that is covered in the original version of the extension. There are two reasons really. First I believe there is a solution that is more Spree extension like than previously done. And second I have not yet setup Amazon S3 account. I will address this shortly but wanted to get this information out right away.

In case you are interested the method for the image override belongs in your site_extension or heroku_extension.rb file. Here is a sample of how to override the default styles and sizes for paperclip in a spree extension inside the def activate block.

Image.attachment_definitions[:attachment][:styles] = {
:mini => '48x48>', :small => '100x100>', :grid => '268x268>',:product => '240x240>', :large => '600x600>'}

Preparing to deploy spree to heroku

Spree comes with a few default preferences. One is to set SSL on in production. In Heroku you have to add SSL as an add-on. There is actually a free option but you have to submit your credit card for verification of identity and to allow you to upscale if needed. So be default Heroku won’t have SSL. This is a quick fix, with 3 lines added to the site_extension.rb file in vendor/extensions/site/ in the activate method.

#site_extension.rb
def activate
  AppConfiguration.class_eval do
    preference :allow_ssl_in_production, :boolean, :default => false
  end
end

Deploy to Heroku

git add . && git commit -m "heroku setup"
git push heroku master
heroku rake db:migrate
heroku rake db:seed

These quick steps will add all the files to your local git repository, push them to your new heroku app, create the production database and seed the default values in the database.

Next is the custom task created in the spree-heroku extension that will create your admin user.

heroku rake heroku:db:admin:create

Finally you are ready to launch your application.

heroku open

I am going to continue working on this and should have an update to the heroku extension that addresses the image storage as I believe it should be. Also I will be working to deploy some other extensions and will possibly write up any future complications.

4 Responses to “Deploying Spree using Heroku”

  1. Sean Schofield

    For rake tasks that require command line interaction, you can also just run them locally and use the taps gem to do rake db:push.

    • Matt

      Thanks.

      I do not have a production site running spree right now. It seemed that either Spree needed more memory than I was prepared to give it. When you look at the footprint on heroku for Spree it is larger than I would prefer. Especially when I am not ready to scale the resources just yet as my client’s site isn’t actually producing sales yet.