Creating Your Own Static Site Publishing System
December 25th, 2009
Installing nanoc
This is an account of the steps I took to install and configure nanoc on NearlyFreeSpeech.net. I chose nanoc because it seemed like the best fit for what I’m trying to accomplish, and NearlyFreeSpeech.net (NFSN) because I like their policies, pricing, and product. These guidelines can be generalized to any Unix- or Linux-based web host, although certain steps may be different. (For instance, if the Mercurial version control software is not installed.) However, I feel it’s important to note that if you don’t understand what I’ve written here, blindly following my example can get you into trouble.
This is really a “nuts and bolts” description of what I did to get nanoc installed and running; I’ll write later about my motivations and goals for this project. First I’ll need a place to write about them.
Many thanks to Denis Defreyne, author of nanoc, for his help.
The first step is to install cri, a program that nanoc depends on.
gem install cri
Step one is to install the latest version of nanoc. Because I like living dangerously, I’ll be installing a beta version with the —prerelease flag.
gem install nanoc3 --prerelease
Note that I didn’t use the “sudo” command. Because I don’t have root access on my web server, I omitted “sudo.” When run as a non-root user, gem will install to the user’s home directory instead of system-wide directories.
Installing nanoc this way should install cri, one of its dependencies.However, it doesn’t seem to do that, so you have to:
Installing nanoc and cri gives us two warnings:
WARNING: Installing to ~/.gem since /usr/local/lib/ruby/gems/1.8 and
/usr/local/bin aren't both writable.
WARNING: You don't have /home/private/.gem/ruby/1.8/bin in your PATH,
gem executables will not run.
The first warning tells us gem did exactly what we want it to do. We do not have root or sudo access, so we WANT to install in our home directory. All is well.
However, the second warning tells us we will not be able to launch gems properly. We will need to update our PATH variable so we can find the Ruby gems we just installed. We’ll need to create two different BASH configuration files, for fairly arcane reasons. In addition to the PATH changes we need to make, we’ll also make an ls colorization change to make our terminal a little more pleasant.
On NSFN, these files do not exist. If they exist for you, do not follow these instructions blindly — you’ll have to figure out the correct way to merge the things we want to add to what’s already there.
cat >> /home/private/.bashrc << EOF
alias ls="ls -G"
export PATH="$PATH:/home/private/.gem/ruby/1.8/bin:/home/private/nanoc/bin/"
export RUBYOPT="rrubygems"
EOF
cat >> /home/private/.bash_profile << EOF
. /home/private/.bashrc
EOF
chmod 744 /home/private/.bashrc
chmod 744 /home/private/.bash_profile
Now if you log out and log back in, you should be able to type “nanoc3” and see help text.
I also decided to install Textile as a replacement for Markdown for my site’s markup language. Markdown seems to be designed to look good on the screen as plain text, before it’s converted to HTML. That’s a fine goal, but I’m not planning to display the plain text anywhere.
Textile, on the other hand, appears to be designed to be quick and easy to edit, with the display intended to be through HTML output.
To use Textile, you have to install the RedCloth gem:
gem install RedCloth
However, it looks like there’s a bug in RedCloth which prevents it from installing completely as a non-root user:
make install
/usr/bin/install -c -o root -g wheel -m 0755 redcloth_scan.so /home/private/.gem/ruby/1.8/gems/RedCloth-4.2.2/lib
install: /home/private/.gem/ruby/1.8/gems/RedCloth-4.2.2/lib/redcloth_scan.so: chown/chgrp: Operation not permitted
*** Error code 71
As a non-root user, I can’t change the owner of a file to root. Even with this error, RedCloth appears to be working fine. (I filed a bug with the RedCloth project about this behavior.)
Nanoc is now installed and running on your web host! Next we’ll look at configuring it and getting a website running.
Configuring Nanoc
Now let’s create our site. Since this documents me building the schof.org site, we’ll name the site “schof.org.”
$ nanoc3 create_site schof.org
I then had to edit my Rules file to run the newly-installed RedCloth filter on all posts:
#!/usr/bin/env ruby
compile '*' do
filter :erb
filter :redcloth
layout 'default'
end
route '*' do
item.identifier + 'index.html'
end
layout '*', :erb
Now all my content will be processed from Textile to HTML. (Of course, I had to edit all two pages on the site at this time to convert them to Textile.)
Now we’ve got the framework for a nanoc site. We can even change directory to /home/private/schof.org and run “nanoc3 compile” and it will create a default HTML page in /home/private/schof.org/output. However, since this is still under the /home/private directory, you can’t see it over the web.
What’s more, our website is not stored anywhere except on NFSN’s servers, so we have no backup — a dangerous place to be.
Let’s copy the BASH startup scripts we created earlier into our schof.org directory structure.
$ mkdir -p /home/private/schof.org/tools/config
$ cp /home/private/.bashrc /home/private/schof.org/tools/config/bashrc
$ cp /home/private/.bash_profile /home/private/schof.org/tools/config/bash_profile
I created a Mercurial repository on BitBucket.org called “”http://bitbucket.org/schof/schof.org/“>schof.org.” Let’s add our /home/private/schof.org files to that.
$ cd /home/private/schof.org
$ hg init
$ hg add *
$ hg commit -m "Initial commit of template nanoc site."
$ hg push http://bitbucket.org/schof/schof.org/
Now we need to clone the output directory to the /home/public directory. However, this is getting a little complicated, and we’re not going to want to do these steps by hand.
Rather than type in the entire script in this article, why don’t you just look at it on bitbucket?
What About A Local Copy?
So now we’ve got a way to automatically publish changes that we check into bitbucket on our website. However, up to now, we can only make those changes on our website. Let’s make that a little easier.
The following steps were taken on an Ubuntu computer. They should work equally well on an OS X computer, with some modifications. (You’d need to install Mercurial differently.) However, as far as I know, they won’t work at all on a Windows computer.
OK. We’ll need to create a local checkout. Step 0 (not covered here) is install Mercurial.
In my home directory (/home/schof) I checked out the schof.org repository into a directory called schof.org.
$ hg clone https://schof@bitbucket.org/schof/schof.org/
Turns out I got tired of typing my bitbucket password into Mercurial every time I ran my push script.
I edited my ~/.hgrc file, and put in the username and password I use for Bitbucket.org. This means hg no longer prompts me for it when checking changes into the repository
[auth]
bb.prefix=bitbucket.org
bb.username=schof
bb.password=ThisIsNotReallyMyPassword
Now, I’ll make a change to one of the files in schof.org. (I edited the heading line in “schof.org/content/index.html.”)
We’ll want a push script to send those changes to the server, and then run the publish_on_server script on the server itself. Again, simply check out the script on bitbucket: <http://bitbucket.org/schof/schof.org/src/tip/tools/push_updates_to_server.bash>
There! We’ve got a fully-functioning, static-page publishing system! All the kids will envy you. Women (or men, if that’s your thing) will swoon.
Next, we’ll cover some performance measurements I’ll want to do periodically for my site. And then we’ll look at customizing nanoc. (As soon as I figure out how to customize nanoc.)