UPDATE: This post has been hugely superceded by this newer one as I’ve moved from shared hosting to Amazon’s EC2 and S3 cloud. Not only is it far more informative, with actual code and everything, it also covers broader automation of Jekyll blogging.
If you’re reading this, I’ve successfully migrated from Tumblr after four years. You may need to update your RSS subscriptions, unless you don’t have one in which case I hate you. If you’re not reading this, I’ve not managed to migrate, but I can always fix whatever’s wrong and then repost this message and you’d be none the wiser.
Why migrate? Tumblr was (generally) easy to post to when it wasn’t keeling over, wheezing, but it was pissing money before Yahoo bought it out for $gazillion. And when you’ve spent $gazillion on something that’s pissing money, generally the first thing you’re thinking is “how do we reverse this flow of piss and/or money?” The answer to that question for free services online is almost always “UNLEASH THE ADS!” Tumblr’s newly-added side flyout and long-time top bar controls are annoying enough without advertising being thrown into the mix. Also, it’s nice to be back in possession of my own output.
And this time it’s not even buried in a WP database somewhere. The site’s run on flat-file Markdown engine du jour Jekyll. The import process has sadly broken lots of things - none of the old internal links between articles will work, anything with a photo has had it stripped and replaced with a [ gallery ] tag, and there are no embeds any more - but still, all the words are there amid the crap and the reposts, on my hard drive and living in Dropbox. I need to add some functionality back in - archives, tags as links, maybe search - but we’re more or less there.
(If dry technical meanderings bore you - very sensible - then stop right now. The bit below is a massive note to self, a tutorial of sorts should I attempt something similar in future, and likely of no interest to anyone else whatsoever.)
Originally I was going to run NH on Marco Arment’s Second Crack. (WordPress, as (mostly) solid a CMS as it is, is way too big and clunky for a site like this.) For all its quirks, it’s a very smart bit of software, and unlike a lot of the flat-file offerings it doesn’t need to remote-build the site then deploy to show static content to visitors; it converts Markdown files to HTML on the fly. And it’s got some natty post-from bookmarklets for easy linking to things.
Unfortunately, it also has to run behind a changed document root (at
secondcrack/www) which, on shared hosting, I can’t change except on subdomains. “Not a problem,” thought I. “I’ll install it to a subdomain, then use
.htaccess to render the content of that subdomain at namelesshorror.com. Seamless!” Which it would be, if SC didn’t have its own
.htaccess needed to do all that on-the-fly file rendering. It turns out - and this is a bad thing to learn at 11pm when you’re hoping to finish something off and go to bed - that they don’t stack. Look, I’ve never had to do much with rewriting before; stop laughing.
Jekyll doesn’t have this problem. It needs to generate the site afresh every time you add/change something, but what it generates can be dropped wherever you want it. You can run it on your PC and FTP or git push your output online if you’re so inclined.
I’m not. That seems to be a massive pain, especially if you write something on your phone and want it up without having to visit the mothership. You can automate things by installing a copy of Jekyll on the server and having it rebuild everything automatically though.
Unless you’re on shared hosting, when
gem install jekyll will give you an error about not being able to write to the system Ruby directory and a feeling of lingering dread.
It turns out, thankfully, that you can get around that by installing RVM instead.
laptop:~$ ssh email@example.com
|server:~$ \curl -L https://get.rvm.io
||bash -s stable –ruby
server:~$ which ruby
server:~$ gem install jekyll
server:~$ gem install pygmentize
So that’s Jekyll installed. And if you install Dropbox and its command line interface, link it to a blog-only account with one folder, the blog one, shared with your actual main one, as per the suggestion in the Second Crack readme, you can run the whole thing through Dropbox.
jekyll new somesitename
Do this on both your home machine and server. This creates a
somesitename directory containing all the Jekyll structure and files.
Symlink that directory to the Dropbox blog one on both.
ln -s /path/to/somesitename /Dropbox/Blog
Jekyll’s source directory is now being read and updated by Dropbox. All you need to do is set Jekyll’s build destination directory, the place the finished site is built in, to
/home/user/public_html or whatever the doc root of your server is in
_config.yml or in the
jekyll build command itself.
And as for auto-updating, while some people recommend incron, that requires root privileges and doesn’t watch directories recursively. There are utilities like Spotter for watching for file changes and running scripts when they happen without being root, but I don’t think they’re needed (yet, anyway). What I have are two shell scripts. The first simply runs dropbox.py (
python2.6 dropbox.py start), and the second runs Jekyll’s build command (
jekyll build --source /Dropbox/Blog/somesitename --destination /path/to/public_html). If I can get them to play nice with cron jobs, we’re gold.
If I can’t, I’ll have to look at the various inotify-type file monitor utilities.
One further note: when Jekyll builds to a directory, it wipes everything that was there before. I had a couple of old test directories and subdomains (including the Second Crack ones) and numerous other bits and pieces stacked beyond public_html. Those are now gone. There may be exception rules you can use to save stuff, but I’m not sure. Best get anything you want to keep out of there before you run it.
One further further note: I’ve tried typing this post three times, the first two in iA Writer on my phone. It turns out iA Writer wipes what you’ve been typing if you switch out of the app even for a moment. Which is really fucking annoying.