Pushing jekyll blog content to Dreamhost using GIT

How to configure a GIT remote at Dreamhost to push blog updates from command line.

Keeping the blog versioned

Initially I forked a theme and started tweaking it. Since with static content blogs you don’t need a database I created a git repo to store jekyll’s folder structure and assets. Also I added a remote private repo in bitbucket (I don’t want anybody to see _config.yml for example).

The initial workflow

The initial workflow was to generate the static content, open a ftp connection and upload the contents of the _site folder. That was OK but since I spend most of my time on the console, having the possibility to push updates to my blog using GIT sounded like a good idea. The question was if that was actually possible with Dreamhost.

A google search found this gist Automatic Git deploys on Dreamhost which was the starting point for this post.

Dreamhost passwordless login

In order to push code to a repo located at Dreamhost we need to be able to login without password. To do so we are going to generate a public SSH key on our machine if we don’t have one:

  $ ssh-keygen -t rsa

Answer yes to all questions and that will create a id_rsa.pub file under your ~/.ssh directory. Now we need to upload that file to Dreamhost. That can be accomplished using FTP or using:

  $ ssh-copy-id <user>@<host>

In OS X Mavericks I didn’t had that command, so I installed it with homebrew:

  $ brew install ssh-copy-id

We should be able to connect to Dreamhost without password now.

Remote repo creation

Now we need to create a repo in Dreamhost in order to push the code:

  $ ssh <user>@<host>
  $ cd ~
  $ mkdir <mydomain_com>.git
  $ cd <mydomain_com>.git
  $ git init --bare

Setting up the post-receive hook

After we initialize the bare repo we need to set up a post-receive hook, that will be triggered every time changes are pushed. The thing here changes a little from the gist I found. Since Jekyll’s default build folder is _site and I want to keep all in one repo I added some extra steps to the hook. The other way to do this would be keeping a simple hook but pointing Jekyll’s build to other folder, if that works for you is not very different than this.

We need to connect to the server again and create a post-receive hook using vi (or the editor you like):

  $ ssh <user>@<host>
  $ cd ~
  $ vi <mydomain_com>.git/hooks/post-receive

Then paste this code:

  #!/bin/bash

  # Replace this line with your real domain name
  DOMAIN=mydomain.com

  echo
  echo "~~ Updating $DOMAIN ~~"
  echo

  # Clearing git env
  unset GIT_DIR
  unset GIT_WORK_TREE

  # auxiliar domain storing the entire jekyll tree (all repo content)
  cd ~/$DOMAIN-jekyll
  git pull

  # get to the static build directory
  cd _site

  # delete domain contents
  rm -rf ~/$DOMAIN/*

  # copy that to our real domain path
  cp -R * ~/$DOMAIN

  echo
  echo "~~ Done ~~"
  echo

Also we need to make this script executable:

  $ chmod +x <mydomain_com>.git/hooks/post-receive

Creating the remote structure

Now we need to create a remote structure. In Dreamhost, we clone the repo we just created:

  $ cd ..
  $ git clone <mydomain_com>.git <mydomain.com>-jekyll

The flow is: Once the changes are pushed, the entire Jekyll folder structure will be sitting on a directory -jekyll. Then the hook will be copying just the static content to your actual directory that is open to the public.

Adding the remote endpoint to our local repository and pushing changes

In our machine we need to add the remote to our local repository.

  $ git remote add live ssh://<user>@<host>/~/<mydomain_com>.git

And that’s it.

We will now be able to push changes straight to our Dreamhost domain with:

  $ git push live master