Automating daily updates to Github Pages using a Raspberry Pi

4 minute read

I’m a big fan of Jekyll for creating static websites using a simple, blog-aware templating system. This saves fiddling with complex HTML code or dealing with hosting providers and Wordpress issues. The advantage of websites built using Jekyll is that they are fast and secure. Part of this strength is also a disadvantage, as being static, there is no back end for handling dynamic content. Some of these shortcomings can be worked around using external services, like Formspree for web-forms, but other things are just not possible with static pages.

In building this website, I wanted a message of the day on the home page (or “motd” for the Unix nerds out there). Back in the “before times” when I would dial into remote systems, I got a kick out of the message of the day on login. This is how I implemented it here on a Jekyll based static website. I’m not saying this is the best (or even recommended) solution, but I like it.

First off, this site is hosted on Github Pages, as Github supports Jekyll natively. To host a site on Github, simply create a repository and upload your Jekyll source files. Github will build the site using Jekyll and present it via your Github Pages URL (custom URLs are also supported). Each time you push an update to your Github repository, the site will be automatically rebuilt. That said, I did not want to manually update the MOTD each day, it needed to be automated. This is where the Raspberry Pi comes in. I already had an old Raspberry Pi Model B running Raspbian at home as a low-power host for handling various simple tasks. For example, it monitors my Twitter feed and actions some things automatically for me (perhaps I’ll post about that in the future).

The first step in automating the process was to install git on the Pi and clone my site from Github. I won’t go into great detail, but here are the basic steps I followed:

sudo apt install git
mkdir ~/git
cd ~/git
git clone https://github.com/...

The key to automating updates to Github from a remote server is using SSH keys. This allows a script to push changes to a repository securely without needing a password. The process for setting up a public SSH key and linking it to your Github account is well documented in the following Github Help pages:

With this done, I could now setup a script to push site changes on a daily basis using cron (more on that later). This still didn’t solve how I was going to change the message of the day randomly without editing the pages manually. After further research, I discovered Jekyll had the capability to select random items from an array using the built-in Liquid templating language. If I stored my selected MOTD quotes in a YAML formatted text file, and placed this file in the site _data directory, it would be read by the Jekyll engine into an array as part of the site build process. Here is a snippet of this file from my site.

/_data/motd.yml

- text: "Adversity does not build character, it reveals it."
  cite: "James Lane Allen"
- text: "The Road to Hell is paved with good intentions."
  cite: "John Ray (1670)"
- text: "All that is required for evil to prevail is for good men to do nothing"
  cite: "Edmund Burke"

Once this data was available as an array in memory, I could use the Liquid sample filter to select a random object from the motd array.

{% assign motd = site.data.motd | sample %} 
<p><code class="highlighter-rouge">/etc/motd</code></p>
<blockquote>{{ motd.text }}</blockquote>
<p class="small">     <cite>{{ motd.cite }}</cite></p>

Now, each time the site was rebuilt, a random quote would be selected from the MOTD file and appear on the home page. The final step was to force a page rebuild on a daily basis. Although no actual code changes, I could force Github Pages to complete a page rebuild by submitting an empty commit. Here is the specific script on my system which handles this.

#!/bin/sh
cd /home/pi/git/bftsystems
# Pull down any changes from Github first to avoid wiping any remote changes
git pull origin master
git commit -m "Force Site Rebuild" --allow-empty
git push origin master

This is scheduled daily in my user crontab file (not the root crontab file), which allows the script to use the Github SSH key in my user profile.

0 0 * * * /home/pi/git/bftsystems/force_site_rebuild.sh

There you have it. It seems like a lot of work to do something which could easily be done by any CMS, but I like keeping everything internal and under my direct control. I already had the Raspberry Pi handling other tasks, so this is just one more task for it to do.

Lastly, this can all be done without Github. You could host your Jekyll code on an AWS instance (or a home desktop PC for that matter), and run a script which performs a daily site build and sync to a remote host (e.g. Amazon S3). Once again, I already had a Github account, so using Github Pages was an easy solution.

If you would like to contact me or provide feedback on this post, use the Contact page, or message me on Twitter. Thanks!