_posts/2015-06-29-hosting-a-jekyll-site-on-heroku.md
---
title: Hosting a Jekyll Site on Heroku
date: 2015-06-29 11:11:30 -05:00
tags:
- development
- Jekyll
- Jekyll on Heroku
layout: post
custom_type: post
subtitle: Avoid pulling your hair out like I did.
---
*This post is part of a series on [hosting Jekyll with Heroku](/topics/#jekyll-on-heroku).*
---
I love using Jekyll. I use it for this blog, my personal site, and it’s the first thing I suggest when people want something with content that needs to be updated. However, deploying gets complicated when you’re using a variety of plugins and you don’t want to host with GitHub Pages.
{% include toc.html %}
I had setup [Deploy](https://www.deployhq.com/) to do this automatically when new commits were pushed to the master branch. But I wanted something better; something that didn’t feel like so much of a hack. I was having to compile the whole site locally, and sometimes I’d forget to use the right config file, so things would break and I’d have to scramble to fix quickly.
One day, the lightbulb when off, and I started to wonder if I could use [Heroku](https://www.heroku.com/home) to host my Jekyll sites. After doing some calculations, I felt like I could improve the deploy workflow, and save a little money.
## So how the heck do you do it?
Well, it was a bigger pain in the butt to figure out than I thought, but once you understand the pieces, it actually is pretty simple. Unfortunately, most of the articles that walk you through this process were published a while ago, so they were using out-of-date gems, and deprecated commands.[^1] But by combining the process of [this article](http://blog.bigbinary.com/2014/04/27/deploy-jekyll-to-heroku.html) and [this article](http://www.jamesward.com/2014/09/24/jekyll-on-heroku), you find yourself with a great solution. Hopefully you’ll find this useful.
### Ignore the Site Folder
First things first, you’ll want to ignore your `_site` folder. You’ll be building the site on the server now, so there’s no need for these files to be cluttering up your repo. In your `.gitignore` add the following line:
```sh
# .gitignore
_site
```
### Exclude Vendor in \_config.yml
You’ll also want to exclude `vendor` in your `_config.yml` file. This folder is generated by Heroku I believe. I didn’t actually test why this needs to be done, but I did it.
```yaml
# _config.yml
excluded: ['vendor']
```
### Add Gemfile
If you don’t have one already, you’ll want to create a `Gemfile`.[^2] I recommend you visit [RubyGems.org](https://rubygems.org/) for the latest versions of these gems.
```ruby
# Gemfile
source "https://rubygems.org"
gem 'foreman'
gem 'jekyll'
gem 'rack-contrib'
gem 'rake'
gem 'thin'
```
Once you’ve got these gems in your `Gemfile`, run `bundle install` and make sure your `Gemfile.lock` is checked into your repo. **The build process will fail without the `Gemfile.lock`.**
### Add Procfile
Next, add a `Procfile`. We’ll be using thin to serve up our site. You do that with the following lines:
```yaml
# Procfile
web: bundle exec thin start -p $PORT -V
console: echo console
rake: echo rake
```
### Add Rakefile
We need to tell Heroku to build our site, and we’ll do that by attaching a command to the `rake assets:precompile` task that Heroku runs. Create a `Rakefile`, and add these lines:
```ruby
# Rakefile
namespace :assets do
task :precompile do
puts `bundle exec jekyll build`
end
end
```
### Add config.ru
Now, we need to tell Rack how to serve up our files. We want it to do this statically so we’ll add a `config.ru` file and add the following lines:
```ruby
# config.ru
require 'rack/contrib/try_static'
use Rack::TryStatic,
:root => "_site",
:urls => %w[/],
:try => ['.html', 'index.html', '/index.html']
run lambda { |env|
return [404, {'Content-Type' => 'text/html'}, ['Not Found']]
}
```
Lastly, make sure you’re using relative URLs for assets. I ran into a javascript error for calling jQuery over an insecure connection. Which meant changing the line.[^3]
```html
<!-- You'll change a line like this -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- To this -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
```
That’s it! Now just push your repo to Heroku, and it’ll build the site and serve it. If you’d like to dig through the repo for this site, [it’s on GitHub](https://github.com/ttimsmith/theboldreport.net).
[^1]: Not to mention, it was difficult to find a pattern of how people do this. You’ll usually do research on something like this and all the blog posts will point you to the same steps. Not here. There were like four different ways, some that seemed simple, and others that were quite complex and required knowledge of routes in Sinatra. Craziness.
[^2]: You can do this by going into your terminal, `cd` into the directory of your Jekyll site, and type `bundle init`. You’ll need to have the bundler gem to do this, so if you don’t have that, type `gem install bundler` into your terminal to install.
[^3]: I add this information because my JS wasn’t working and I spent like 20 minutes just scratching my head as to why. Opened the console, and found the issue immediately. Should’ve done that in the first place.