Deploying sites with Apache, Jekyll, Sass and Git
After the huge rambling thing I did last time, let's see if I can be a little more focussed. This is how I deploy the static bits of my site.
I keep the source files in git - I have a copy in this github for convenient pointing/examples. I build the site with Jekyll, which uses _config.yml
as its config file. This file is blank. This is because I like the defaults. In accordance with Jekyll defaults, the layout templates for the site are in _layouts
.
In this directory, I run jekyll --auto . /tmp/jekyll
, which processes the whole directory tree into /tmp/jekyll
(just to keep it out of the way) - if a file starts with a YAML header it'll process it as a Jekyll source file, otherwise it'll just copy it straight across. The process also stays running (that's the --auto
), watching for changes. This way I can edit source files and see changes instantly.
I build several domains-worth of pages at once using this tree. tom
corresponds to http://tom.movieos.org and toys
to http://toys.movieos.org. To preview this on my local computer, I have a few entries in /etc/hosts
:
127.0.0.1 tom.movieos.local
127.0.0.1 toys.movieos.local
and a local apache config file containing:
<Directory "/tmp/jekyll/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<VirtualHost *:80>
ServerName tom.movieos.local
DocumentRoot /tmp/jekyll/tom
</VirtualHost>
<VirtualHost *:80>
ServerName toys.movieos.local
DocumentRoot /tmp/jekyll/toys
</VirtualHost>
This way, I can open http://tom.movieos.local. in my browser, and see the local processed files. Useful!
Just to keep things interesting, I also don't use CSS, I like to write sass. Now, there's a branch of Jekyll that knows about sass, but I can't get it to work - instead I use compass. config.rb
in my site root is the compass configuration file. I run compass -w
in the root of the repository and, like Jekyll, it will run and watch for changes, and rebuild the CSS files from the .sass files when I change them. Then Jekyll will see that they have changed and update the built site. More overhead, but it works very well.
When I'm happy, or whenever I've made some interesting changes, obviously I check things into the local git repository. Then I push the changes to the bare repository that lives on my colo. In that repository, I have a post-update hook:
#!/bin/sh
unset GIT_DIR
&& cd /home/tomi/web/movieos
&& git pull
&& compass
&& jekyll . /home/tomi/web/movieos_generated
So. I unset GIT_DIR
because I'm about to talk to a different repository and don't want to confuse things. Then I go to the directory where I have the source files checked out, and git pull
to get them up to date. A single run of compass
generates the CSS files in that directory, then I run jekyll
to build the generated site.
Finally, Apache serves them. Rather than hard-code all my domains as I have locally, I'm more complicated on the server. I have a wildcard DNS entry that points *.movieos.org to the server. My apache config looks like this:
<VirtualHost *:80>
# This virtualhost matches _anything_ in the movieos.org domain
ServerName wildcard.movieos.org
ServerAlias *.movieos.org
ServerAdmin tom@jerakeen.org
# not used
DocumentRoot /home/tomi/web/movieos_generated/tom
UseCanonicalName Off
# match the first atom of the requested hostname, and serve files
# out the directory with that name
RewriteEngine on
RewriteCond %{http_host} .
RewriteCond %{http_host} ^([^.]+).movieos.org [NC]
RewriteRule ^(.*) /home/tomi/web/movieos_generated/%1$1 [L]
DefaultType text/plain
DirectoryIndex index.php index.html
</VirtualHost>
This way, http://tom.movieos.org/ is served by files in /home/tomi/web/movieos_generated/tom
, and likewise for all my other subdomains.
So that's it. A post-commit hook runs two sorts of processors over the source, building it into a directory tree that's served using Apache rewrite rules. Complicated and maybe fragile, but only at deploy time - because they're static files, once they're there, they stay there.