☑ Website Maintenance on the Move

19 Sep 2016 at 1:45PM in Software
 |  | 

I write most of my blog articles and make other changes to my site whilst on my daily commute. The limitations of poor network reception different hardware have forced me to come up with a streamlined process for it and I thought it might be helpful to share in case it’s helpful for anyone else.

laptop hands

I like writing. Since software is what I know, I tend to write about that. QED.

Like many people, however, my time is somewhat pressured these days — between a wife and energetic four-year-old daughter at home and my responsibilities at work, there isn’t a great deal of time left for me to pursue my own interests. When your time is squeezed the moments that remain become a precious commodity that must be protected and maximimsed.

Most of my free time these days is spent on the train between Cambridge and London. While it doesn’t quite make it into my all time top ten favourite places to be, it’s not actually too bad — I almost invariably get a seat, usually with a table, and there’s patchy mobile reception along the route. Plenty of opportunties for productivity, therefore, if you’re prepared to take them.

Since time is precious, the last thing I want to do when maintaining my blog, therefore, is spend ages churning out tedious boiler-plate HTML, or waiting for an SSH connection to catch up with the last twenty keypresses as I hit a reception blackspot. Fortunately it’s quite possible to set things up to avoid these issues and this post is a rather rambling discussion of things I’ve set up to mitigate them.

Authoring

The first time-saving tool I use is Pelican. This is a source code generator which processes Markdown source files and generates static HTML from them according to a series of Jinja templates.

When first resurrecting my blog from a cringeworthy earlier effort1 the first thing I had to decide was whether to use some existing blogging platform (Wordpress, Tumblr, Medium, etc.) either self-hosted or otherwise. The alternative I’d always chosen previously was to roll my own web app — the last one being in Python using CherryPy — but I quickly ruled out that option. If the point was to save time, writing my own CMS from scratch probably wasn’t quite the optimal way to go about it.

Also, the thought of chucking large amounts of text into some clunky old relational database always fills me with a mild sense of revulsion. It’s one of those solutions that only exists because if all you’ve got is a hosted MySQL instance, everything looks like a BLOB.

In the end I also rejected the hosted solutions. I’m sure they work very well, with all sorts of mobile apps and all such mod cons, but part of the point of all this for me has always been the opportunity to keep my web design skills, meagre as they might be, in some sort of barely functional state. I’m also enough of a control freak to want to keep ownership of my content and make my own arrangements for backing it up and such — who knows when these providers will disappear into the aether.

What I was really tempted to do for awhile was build something that was like a wiki engine but which rendered with appropriate styling like a standard website — it was the allure of using some lightweight markup that really appealed to me. At that point I discovered Pelican and suddenly I realised with this simple tool I could throw all my Markdown sources into a Git repository and then throw it through Pelican2 to generate the site. Perhaps I’m crazy but it felt like a tool for storing versioned text files might be a far more appropriate tool than a relational database for, you know, storing versioned text files. Just like a wiki, but without the online editing3.

All there was to do then was build my own Pelican template, set up nginx to serve the whole lot and I was good to go. Simple enough.

Updating the site

Except, of course, that getting site generated was only half the battle. I could SSH into my little VPS, write some article in Markdown using Vim and then run Pelican to generate it. That’s great when I’m sitting at home on a nice, fast wifi connection — but when I’m sitting at home I’m generally either spending time with my family or wading through that massive list of things that are way lower on the fun scale than blogging, but significantly higher on the “your house will be an uninhabitable pit of utter filth and despair” scale.4

When I’m sitting on a train where the mobile reception varies between non-existent and approximately equivalent to a damp piece of string, however, remote editing is a recipe for extreme frustration and a string of incoherently muttered expletives every few minutes. Since I don’t like to be a source of annoyance to other passengers, it was my civic duty to do better.

Fortunately this was quite easy to arrange. Since I was already using a Git repository to store my blog, I could just set up a cron job which updated the repo, checked for any new commits and invoked Pelican to update the site. This is quite a simple script to write and the cron job to invoke it is also quite simple:

*/5 * * * *     git -C /home/andy/www/blog-src pull; \
                /home/andy/www/blog-src/tools/check-updates.py

If you look at check-updates.py you’ll find it just uses git log -1 --pretty=oneline to grab the ID of the current commit and compares it to the last time it ran — if there’s any difference, it triggers a run of Pelican. It has a few other complicating details like allowing generation in a staging area and doing atomic updates of the destination directory using a symlink to avoid a brief outage during the update, but essentially it’s doing a very simple job.

This was now great — I could clone my blog’s repo on to my laptop, perform local edits to the files, run a staging build with a local browser to confirm them and then push the changes back to the repo during brief periods of connectivity. Every five minutes my VPS would check for updates to the repo and regenerate the site as required. Perfect.

There’s an app for that

Well, not quite perfect as it turns out. While travelling with a laptop it was easy to find a Git client, SSH client and text editor, but sometimes I travel with just my iPad and a small keyboard and things were a little trickier.

However, I’ve finally discovered a handful of apps that have streamlined this process:

Working Copy
Since I put Git at the heart of my workflow it was always disappointing that it took so long for a decent Git client to arrive on iOS. Fortunately we now have Working Copy and it was worth the wait. Whilst unsurprisingly lacking some of the more advanced functionality of command-line Git, it’s effective and quite polished and does the job rather nicely. It has a basic text editor built in, but one of its main benefits is that it exposes the working directory to other applications which allows me to choose something a little more full-featured.
Textastic
This is the editor I currently use on both iOS and Mac. It’s packed with features and can open files from Working Copy as well as supporting direct SFTP access and other mechanisms. I won’t go through it’s myriad features, just suffice to say it’s very capable. I should give an honourable mention to Coda for iOS, Panic Inc.’s extremely polished beautifully crafted text editor for iOS, which I used to use. Coda has a builtin SSH client and is really heavily optimised for remote editing, so it’s a great alternative if you want to explore. The original reason I switched was that, with my unreliable uplink, Textastic‘s more explicit download/edit/upload model worked a little better for me than Coda’s more implicit remote editing with caching. Now the fact that Textastic supports local editing within the Working Copy repo is also a factor. I’ll also be totally honest and point out that I haven’t played with Coda since they released a (free) major update awhile back. I’ve nothing but praise for its presentation and overall quality, however.
Prompt 2
If Coda for iOS didn’t quite tempt me as much as Textastic, another of Panic’s offerings Prompt 2 is absolutely exactly what I need. This is by far the most accomplished SSH client I’ve used on iOS bar none. It supports all the funtionality you need with credentials, plus you can layer Touch ID on top if you want it to remember your passphrases. Its terminal emulation is pretty much perfect - I’ve never had any issues with curses or anything else. It runs multiple connections effortlessly and keeps them open in the background without issue. It can even pop up a notification reminder to swap it back to keep your connections alive if it’s idle for too long. As with any remote access on a less than perfect link I’d very strongly suggest using tmux, but Prompt 2 does about all it can to maintain the stability of your connections.

Summary

That’s about the long and the short of it, then. I’ve been very happy with my Git-driven workflow and found it flexible enough to cope with changes in my demands and platforms. Any minor deficiencies I can work around with scripting on the server side.

The nice thing about Git, of course, is that its branching support means that if I ever wanted to set up, say, a staging area then I can do that with no changes at all. I just create another commit on the server which uses the staging branch instead of master, and I’m good to go — no code changes required, except perhaps some trivial configuration file updates.

Hopefully that’s provided a few useful pointers to someone interesting in optimising their workflow for sporadic remote access. I was of two minds whether to even write this article since so much of it is fairly obvious stuff, but sometimes it’s just useful to have the validation that someone else has made something work before you embark on it — I’ve done so and can confirm it works very well.


  1. Not to be confused with a hilariously precocious first version that I created shortly after I graduated. 

  2. You may be more familiar with Jekyll, a tool written by Github co-founder Tom Preston-Werner which does the same job. The only reason I chose Pelican was the fact it was written in Python and hence I could easily extend it myself without needing to learn Ruby (not that I wouldn’t like to learn Ruby, given the spare time). 

  3. Of course, one could quite reasonably make the point that the online editing is more or less the defining characteristic of a wiki, so perhaps instead of “just like a wiki” I should be saying “almost wholly unlike a wiki but sharing a few minor traits that I happened to find useful, such as generating readable output from a simple markup that’s easier to maintain”, but I prefer to keep my asides small enough to fit in a tweet. Except when they’re talking about asides too large to fit in a tweet — then it gets challenging. 

  4. The SI unit of measurement is “chores”. 

19 Sep 2016 at 1:45PM in Software
 |  |