3 min read

The Super Simple Way to Add a Jekyll Based Blog in Your Rails Application

In my original post I talked about setting up Jekyll inside your existing Rails application via gems and modifying your config.ru file. We can simplify the process even more than that though.

Jekyll is just a static site generator so all we need to do is be able to publish it within our Rails application’s public directory and our web server will take care of it from there. It also doesn’t need to be coupled to our Rails application, it can just sit in our Rails application, similar to static uploads.

What we’ll be doing is just adding a shared directory to our deploy recipe for where the blog will go. From there we can just build and rsync the Jekyll site to our blog directory. Easy peasy.

I’m going to start from scratch but if you already have a Rails application feel free to skip this step.

$ mkdir ~/src/little-feedback
$ cd ~/src/little-feedback
$ rails new little-feedback
$ cd little-feedback
$ bin/rails server

Now that we have our Rails application running in ~/src/little-feedback/little-feedback we can create our blog in a sibling directory.

$ cd ~/src/little-feedback
$ gem install jekyll
$ jekyll new blog

Once Jekyll finishes creating your blog, modify your _config.yml file’s baseurl option to point to /blog. This is important so that assets load and everything links properly.

baseurl: "/blog" # the subpath of your site, e.g. /blog

Now we have our blog in ~/src/little-feedback/blog and our Rails application in ~/src/little-feedback/little-feedback. To demo the setup we’ll add a deploy script that just builds Jekyll and rsyncs it to our local Rails application’s public directory. If you don’t have rsync installed, you’ll need to install with your favorite package manager.

This flow will be identical to how it’ll sit on the server it’ll just be an rsync to your server(s) to the appropriate directory instead of a local file path.

Create a deploy script to simplify your project specifics within the ~/src/little-feedback/blog directory:

~/src/little-feedback/blog/bin/deploy:

#! /bin/sh

jekyll build
rsync -va _site/ ../little-feedback/public/blog

It’s a good idea to make it executable as well:

chmod +x ~/src/little-feedback/blog/bin/deploy

Go ahead and run the blog deploy script, you’ll see rsync run and if you look in your Rails application’s public directory you’ll see you have your built Jekyll blog.

➜  ls ~/src/little-feedback/public/blog
about      bin        css        feed.xml   index.html jekyll

Great, now you can work on the application and the blog independently without mixing dependencies. Much better.

If you’re going to be working on both locally I’d also recommend adding public/blog to your .gitignore file within your Rails application so you’re not committing Jekyll/blog files to your application.

echo "public/blog" >> ~/src/little-feedback/little-feedback/.gitignore

The simple Jekyll bin/deploy script works great for local development but for production we need to configure our deploy workflow to incorporate this change. For this application I’m going to be using Capistrano so I’ll add the blog/ directory as a linked_directory in your deploy recipe(~/src/little-feedback/little-feedback/config/deploy.rb):

set :linked_dirs, %w{public/blog log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

Whatever you’re using to deploy you just need to make sure that the blog directory persists independently of any application changes since it sits within the Rails application. With blog/ added as a symlinked directory within your Rails application you can deploy whenever and the blog directory will persist with your Jekyll blog. Now you’ll just need to update your blog’s bin/deploy script to rsync to the proper directory on your server(s), something like the following:

#! /bin/sh

jekyll build
rsync -va _site/ user@example.com:~/little-feedback/production/shared/public/blog

Go ahead and deploy your site to your new blog directory and you should see everything up there. Yay.