It has been just under a month since I launched this blog, and the first thing I promised myself was to automate deployment. If you have an existing GitHub account you might want to consider GitHub Pages, it’s quick and easy.
I am interested in achieving the same functionality offered by GitHub Pages with DreamHost. That is, a single push automatically generates the site, removing the pain of manually copying files and directories.
We are going to create a bare repository for pushing to. Every time you push, we will use the post-receive hook to execute a Bash script. The Bash script clones the repository with a working directory, executes jekyll and cleans up. Hooks in Git behave like events.
Jekyll is not available on DreamHost. You will need to build your own RubyGems and install Jekyll with its dependancies. John Nunemaker has written an excellent guide.
If you are interested in code highlighting, you will also want to install Pygments. Pygments is a Python syntax highlighter that Jekyll uses to parse and wrap your code snippets in the appropriate HTML tags.
$ mkdir ~/lib/python
$ echo 'export PYTHONPATH="$HOME/lib/python:/usr/lib/python2.3"' >> ~/.bash_profile
$ source ~/.bash_profile
Download and build Pygments from source.
$ cd ~/src
$ wget http://pypi.python.org/packages/source/P/Pygments/Pygments-1.0.tar.gz
$ tar -xvzf Pygments-1.0.tar.gz
$ cd Pygments-1.0
$ python setup.py install --home=$HOME
Initialise a bare repository to push to. It is potentially dangerous to push to a remote repository with a working directory.
$ mkdir ~/src/your_git_repo.git
$ cd ~/src/your_git_repo.git
$ git --bare init
Add DreamHost as a remote in your local repository.
$ git remote add dreamhost ssh://user@server.com/home/user/src/your_git_repo.git
Write a Bash script to clone the repository, execute Jekyll and clean up. Jekyll will generate its output in to your publicly accessible directory.
# ~/bin/generate_public_www
#!/bin/bash
GIT_REPO=$HOME/src/your_git_repo.git
TMP_GIT_CLONE=$HOME/tmp/your_git_repo
PUBLIC_WWW=$HOME/var/www/your_site
git clone $GIT_REPO $TMP_GIT_CLONE
jekyll $TMP_GIT_CLONE $PUBLIC_WWW --pygments
rm -Rf $TMP_GIT_CLONE
exit
$ chmod +x ~/bin/generate_public_www
Add the Bash script in the post-receive hook of your bare repository. Hooks are Bash scripts too.
# ~/src/your_git_repo.git/hooks/post-receive
#!/bin/sh
$HOME/bin/generate_public_www
exit
$ chmod +x ~/src/your_git_repo.git/hooks/post-receive
Congratulations, you’re done! Every time you push to DreamHost, Jekyll will build the site. Cool, huh?!
$ git push dreamhost master
Bonus: You now have a redundant copy of your repository.
Jay Williams followed this guide and experienced an annoying problem with the Git post-receive hook. After some trouble-shooting, it appeared that the hook was never executed because the user he was shelling in with didn’t have the access to the compiled binaries in its path.
Copying your .bash_profile to .bashrc should solve the issue for non-login shells.
$ cd ~/
$ cp .bashrc .bashrc.old
$ cp .bash_profile .bashrc
I no longer recommend using this configuration for deployment. See simpler deployment for Jekyll using a Rakefile and rsync.
Tate Johnson is a 23 year old Ruby on Rails developer and university student living in Brisbane, Australia. He enjoys riding bicycles, motorbikes, taking photos and travelling.