Jekyll on Heroku

29 Dec 2009

This blog is published using Jekyll. Jekyll is a static site generator, so you write your posts and pages on your local machine, generate your static HTML site and then publish it using a service that serves static files. Like GitHub Pages or Slicehost.

But neither of those services are free, and my blog has nowhere near enough traffic that it should cost me money, so I wanted to use the free Heroku plan. This is the method I have been using to publish my blog for the past month.

Basically Heroku treats my blog like its a Sinatra app. When you hit the root of the application it serves the index.html from the _site/ folder, and then the links from that page take the user where they want to go.

Simplicity

I recently noticed that there is a project called rack-jekyll that is supposed to make it easy to publish your Jekyll site with Rack. I tried out this project and it failed miserably when trying to display my blog.

The method here is much simpler. The nice thing about the fact that this is a Sinatra app is that you have some built in niceties. Want custom 404 pages? Sinatra has that. Need to demonstrate some dynamically generated code? Just set up another route and go right ahead.

Local Development

Use the jekyll --auto --server command to develop locally.

Deploying

To deploy your jekyll site to Heroku:

  1. Make sure that your _site/ folder is not in the .gitignore file.
  2. Add the two files from the gist above.
  3. Commit changes.
  4. heroku create (first time around)
  5. git push heroku master

Notes on git pushing

27 Dec 2009

Pushing all local branches

Executing

 
git push

is the same as executing

git push origin

In other words it will update all local branches in the remote origin repository. For example, if you have a local master branch and a local experimental branch, both of which have local changes not pushed, then running git push will update both remote branches.

Pushing the current local branch

Say you are working in your local master branch and want to push your changes, but don’t want to update all branches. You can run the git push command, passing in the remote and the name of the branch you want to update:

git push origin master

Pushing to a named remote branch

So, what if have changes in your master branch that you want to push to the remote experimental branch? You could checkout your experimental branch, cherry pick the changes and then use the method above to push those changes, but that’s no fun.

You can actually specify that you want to push your changes to some branch with a different name than the one you are working on with something like this:

git push <remote> <from>:<to>

In our example we would fill in the blanks like so:

git push origin master:experimental

This tells git to push the changes from your local master branch to the remote experimental branch. And we didn’t even need to write /refs/heads anywhere ;)

Deleting remote branches

I discovered a while ago the way to delete remote branches. For example, if we wanted to delete our remote experimental branch we would issue this command:

git push origin :experimental

At first I was thinking ‘Wow! That looks really dumb and makes no sense.’ But, if you look at the above section it makes perfect sense. Think of it this way:

git push origin <nothing>:experimental

It’s as if we are pushing nothing into the experimental branch. The same way we pushed the master branch into the experimental branch above.

I like to think that I’m not bad at writing SQL. When it comes to writing complex queries, joinging tables, grouping columns, sorting, I’m quite comfortable.

However I never seem to give any thought to the possible size of the tables I am working with. Are there hundreds of records? Hundreds of thousands? Millions? This is usually not an issue for local development, however once your app is out in the wild, this is a big issue.

Recently, I have been using two awesome Rails plugins to remind me to not forget these things.

Query Reviewer

http://github.com/dsboulder/query_reviewer

This plugin is great. Basically it adds a js widget to all your pages that runs the EXPLAIN command on each of your queries and lets you know if any warnings were generated.

Just install the plugin and it will be working by default in your development environment. For each problem query, the Query reviewer widget will tell you what the problem is, ie. ‘No index was used. Performed full table scan’, ‘A temporary table had to be used’, etc.

Here is an example where you need to fix something, adding an index in this case.

Here’s where you hope to get to:

Bullet

http://github.com/flyerhzm/bullet

This library detects N+1 queries and unused eager loading. Again, something that you probably wouldn’t notice in a development environment but can become very important in a production environment.

For me this is even more important because I am beginning to understand SQL indexes and where they should be used, but eager loading still escapes me at most junctions.

For Bullet, you need to add some config code to your development environment. By default it logs problems to the Rails log, as well as giving you a js alert. You can even get this thing working with Growl, if you’re into that kind of thing.

Here is an example of its output, its pretty smart with its suggestions:

Conclusion

These plugins are a great way to catch database optimizations that you might have missed. However, these suggestions should be taken with a grain of salt. Much like code metrics, they can only go so far. You know your app better than these tools and in some cases it may be the right decision to ignore them.

I wanted to try experimenting with SVD recommenders in Ruby (via this fantastic blog post http://www.igvita.com/2007/01/15/svd-recommendation-system-in-ruby/) and was having a hell of a time trying to install Ruby’s linalg. When I saw that there was also an example using rb-gsl, I was thrilled because rb-gsl is available from MacPorts. No problem, right? Wrong!

Currently if you try to install rb-gsl form MacPorts (on Snow Leopard) you will get a build error. If you download the latest release of rb-gsl (1.10.3 at the time of this writing) you will get the same build error. It appears to have some code that doesn’t work on Snow Leopard. Here is how I got it installed.

  1. If you haven’t already, install MacPorts for Snow Leopard (http://forums.macrumors.com/showthread.php?t=720035)
  2. Install the GSL library
    $ sudo port install gsl plotutils
  3. Because of the incompatibility of the current rb-gsl and Snow Leopard, you will have to install from the latest svn checkout.
    $ svn checkout svn://rubyforge.org/var/svn/rb-gsl
    $ cd rb-gsl/trunk/rb-gsl
    $ sudo ruby setup.rb config --prefix=/usr/local
  4. Then we need to edit two lines in the generated ext/Makefile
  5. Open up the file for editing and change these two lines to look like this:
    DLDFLAGS = -L.
    LDSHARED = $(CC) -pipe -bundle -undefined dynamic_lookup
  6. Then continue with the build and you should be on your way
    $ sudo ruby setup.rb setup
    $ sudo ruby setup.rb install

Enjoy!

If you are installing this lib to test out the example from above then you may want to check out my comment on that article.

Sources:
http://rubyforge.org/forum/forum.php?thread_id=19389&forum_id=1225
http://rubyforge.org/forum/forum.php?thread_id=45613&forum_id=1225

This week I wrote up a basic sinatra app that allows you to work with the Shopify API. It’s basically just a port of the shopify_app rails plugin to sinatra.

Why?

I have been having fun working on Shopify apps lately, but I needed a simpler way than always generating a new rails app, new controllers, etc., for every little idea.

Rails is great, but most of the Shopify apps that I have come up with are one page apps, maybe two or three pages. The point is, I don’t need a controller for that, I don’t need the 63 files or however many the rails generator generates for me.

Sinatra is most awesome when you are working on a small app with just a few routes. You can clone this app and use it as a starting point for a shopify_app. All of the authentication logic/routes are in the lib folder, so they don’t pollute the code of your app.

So in app.rb, you just have to worry about the functionality of your app.

Usage

The fastest way to get this thing running:

  • git clone git://github.com/jstorimer/sinatra-shopify
  • cd sinatra-shopify
  • heroku create (make sure that you remember the name of your app as you will need that later)
  • visit the Shopify Partners area
  • Sign up for an account if you don’t already have one
  • Log in to your Shopify partners account
  • Create a new application.
  • Make sure that the Callback URL is set to http://yourapp.heroku.com/login/finalize
  • In the lib/sinatra/shopify.yml file replace API_KEY and SECRET with the Api Key and Secret that you just got from the Shopify Partners area
  • git push heroku master
  • heroku open

The current implementation for authentication is to add the authorize! method at the top of any routes that you want to be authenticated, like so:

Gimme the code!

http://github.com/jstorimer/sinatra-shopify

Disclaimer

I am by no means a sinatra expert, this is really my first experience with sinatra. So if you see anything that could be done better, the source is on Github, fork away.