GitHub Pages is a wonderful free platform GitHub has created to build and host your Jekyll sites for you. You push up any valid Jekyll site to a repo (on a special branch), and it's built and published to a predictable URL. The only downside? You can't use any custom Ruby code, which means no custom plugins. So what's the best way to host a Jekyll site that requires plugins?
Maybe you're writing a huge website for your employer, or just something small for yourself. Either way, you need a plugin or two to get it just right. You could build locally and push the compiled site up to GitHub Pages, but that requires that you install all the dependencies locally and write a script to compile and jostle things in just the right way to make it all work. What if you could have the same workflow – just git push
– for sites with custom plugins?
You can. I do it every day. In fact, my personal site (https://parkermoo.re) is published with this method. Here's a step-by-step guide to making your own GitHub Pages.
1. Install and Configure Dependencies
You'll need the following:
- A server with
root
access. I use a Rackspace CentOS 1GB Performance VM, but you can use any Linux system from any provider. - A web server if you don't have one already (Apache/Nginx).
- Ruby and RubyGems with the proper permissions to install new gems.
- Git
- Gitolite
First, sudo su - root
. Then install Ruby. I suggest using rbenv
to keep your Rubies organized. Then ensure RubyGems is installed, and install the github-pages
gem.
Next, ensure you have a daemonized web server installed, like nginx
or apache
.
Then ensure git is installed and create a new git
user. Run su - git
and install gitolite
.
Once you have gitolite
installed, go back to your local machine and configure gitolite
as described. You'll need to add a new user for your SSH key and create the repo for your site.
2. Add the post-receive hook
Run sudo su - git
and find the post-receive
file in your repository. It's usually at /home/git/repositories/MY_REPO.git/hooks/post-receive
. Edit it so it looks like this:
set -e # fail on error
# ensure you have loaded git's environment with rbenv/ruby/jekyll in the path
source /home/git/.bash_profile
# this is only if you have rbenv installed
# remove if you're using a stock ruby
eval "$(rbenv init -)"
# this shows you where the Jekyll executable can be found
# it will also fail if jekyll can't be found, halting the build.
which jekyll
# this is the name of your repo, without the `.git`
REPO_NAME="MY_REPO"
GIT_REPO=$HOME/repositories/$REPO_NAME.git
TMP_GIT_CLONE=/tmp/$REPO_NAME
# Change this to wherever your server (nginx/apache) will look
# for your compiled site. Usually called the document root.
PUBLIC_WWW=/var/www/$REPO_NAME
git clone $GIT_REPO $TMP_GIT_CLONE
# Run Jekyll!
cd $TMP_GIT_CLONE && jekyll build -d $PUBLIC_WWW --trace
rm -Rf $TMP_GIT_CLONE
exit
This hook will clone your repo to /tmp
and run jekyll build
from your site source into the directory your server will serve from.
3. Add the git remote
Go back to your local site and add the remote:
$ git remote add publish [email protected]:MY_REPO.git
4. Test
Now, to test, just push!
$ git push publish master
You should see all the output of the Jekyll process in your terminal. Once you see ...done.
and the process exits, you're done! Refresh your browser and admire your handiwork.
If you get a LoadError
from Jekyll, then you don't have a gem installed or it can't access the _plugins
directory. To install new gems, just run gem install GEM_NAME
as root
on your VM.