A while back, when I found out LibreELEC on a Raspberry Pi 3 won’t play newer MKV video formats, I decided to replace it with my spare 2014 Mac mini. All went well, Kodi runs a lot better and I get smooth playback of even the most demanding movies and tv shows. Then I thought: ‘Why don’t I use it as a local Jekyll server as well and save on my VPS costs?’ And that’s exactly what I did…

The struggle of finding the right approach

As always, there are more than just one way to solve a tech puzzle. Some are good, and some wreck your head.

The one that gave me proper headaches involved locally generating all HTML files and then rsync them onto my web server. It worked very intermittently. This was down to the fact that I haven’t found a single solution that would ensure a stable FTP connection with my web hosting account. It repeatedly asked for login details, even though I stored it in the app’s settings for that particular connection. I spent about half a day trying different apps to map that FTP space as a network drive to my Mac mini, and even fiddled with the FTP configuration files (I am the owner/admin of the web hosting server).

And then I tried going with Git Pages as well. The idea behind is is awesome but the limitations in terms of themes and features are just too much to digest so dropped this one also.

Eventually, I ended up using Git. My web hosting account is Git-enabled and can auto-deploy files directly to the www root of my website (this very blog, actually) with every git push of the newly generated files.

The publishing workflow

To get an idea how publishing works with what I will describe later on. The user point of view version would be:

  1. I create a markdown document (my blog post) and save it to my Dropbox folder.
  2. My post/blog is updated no later than 15 minutes since saving the file.

The behind the scenes version is a little more ‘interesting’:

  1. I create my new post, which is basically a markdown file, and save it in a Dropbox folder.
  2. Files are synced onto my Mac mini server as soon as I add them to my Dropbox account. This goes for any images as well.
  3. On this Mac mini server a crontab task is triggered every 15 minutes. This executes a script, which syncs the markdown files with the _posts folder of my Jekyll based blog. It also syncs any images it finds in a dedicated image folder to the assets directory.
  4. It then runs the jekyll build command and waits for it to finish.
  5. Once the build is finished, the generated HTML files are pushed to my Git repository on the web hosting account.
  6. The new post is published at latest 15 minutes from saving the file onto my Dropbox.

I must admit I like this approach a lot. Compared to my previous arrangement, which had me solve numerous problems with installation and configuration of Dropbox on a GUI-less Ubuntu server, this is just awesome as it all just works.

Okay, I should probably share how I achieved the —practically— two step Jekyll blog publishing using a spare macOS machine and Git-enabled web hosting account 🙂

Skills required, and a word of warning

Before I get into explaining how it’s all done, there are two things I need to make clear right at the start:

  1. In order to complete this tutorial you need to know how to work with the Terminal app on macOS. You also need to know how to install Ruby/Jekyll/Dropbox on your Mac, and add your Jekyll blog. Knowledge of Git is also required.
  2. If you decide to fiddle with your Mac, you do so at your own risk. I will not be held responsible for any mess or damage done to your Mac through your own actions. If your Mac is a ‘mission critical’ tool for you, do a full Time Machine backup before you start!

Here we go then…

Follow this ‘checklist’ to get things ready for the tutorial:

  1. Install Jekyll on macOS
  2. Create your Jekyll blog
  3. Install Dropbox app. If you don’t have a Dropbox account, you can sign up using my share link – you’ll get extra 500MB of space for free 🙂
  4. Inside the Dropbox folder create a directory where you’ll store your markdown (post) files and images.

    For the purpose of this tutorial, I named my folders as ‘jekyllposts’ and inside this directory I created a folder called ‘images’. If you decide to call them differently, that’s fine, just make sure you update the paths in the script that handles all the publishing magic.

Configure Git on your web hosting account

For the whole thing to work you will need to initialise Git in the ~/myblog/_site directory.

When it comes to the remote web server side, there are a lot of web hosting offers out there with Git support built-in. Find one, and configure Git with the ‘Local repository on your workstation’ and ‘Files from the repository will be automatically deployed to/httpdocs/ directory.’ option.

When done, follow the info on how to connect your Mac to your web hosting account’s Git repository.

Where you find that info is different with each web host so you’ll need to do some digging on your own, I’m afraid. One of the steps should be initialising your Git repo on your Mac, which will ask you to login to your web hosting account’s FTP.

If you can’t find any cheap static HTML web host, contact me. I do my own web hosting service for a few years now and I’ll be happy to run your static HTML website for a reasonable fee on my servers in Northern America or Europe.

Create the crontab task

First we need to create the shell script, which will be executed every 15 minutes. Then we create the crontab task itself.

The script

You can create the script file either using your favourite plain text editor, or via the Terminal app with the ‘vi’ editor.

Create a file, name it jekyll_script.sh (again, you can name it what you want as long as you remember to change the file paths in the crontab task at a later stage). I saved it into my Dropbox root folder (where you save it is up to you but you’ll need to reflect that when adding the crontab task).

Copy and paste the following into the newly created .sh file:

#!/bin/sh
if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi
if  [ -f "$HOME"/.profile ]; then
    source "$HOME"/.profile
elif [ -f "$HOME"/.bash_profile ]; then
    source "$HOME"/.bash_profile
elif [ -f "$HOME"/.bashrc ]; then
    source "$HOME"/.bashrc
fi
rsync -a --exclude=/images ~/Dropbox/jekyllposts/ ~/myblog/_posts --delete
rsync -a ~/Dropbox/jekyllposts/images/ ~/myblog/assets
cd ~/myblog
jekyll build 
cd ~/myblog/_site/
git add -A
git commit -m 'website update'
git push

The first line is very important, do include it or the script won’t execute!

The next few lines after the #!/bin/sh are a necessary evil, I won’t waste time explaining what it does – suffice to say it makes the rest of the script work 🙂

The important part starts with the rsync keyword. The first rsync line syncs the posts into the _posts directory of your Jekyll blog. The line underneath it does the same for images, which need to be copied over to the assets folder.

Then the script jumps into the blog’s directory where it executes the jekyll build command. This will generate a static version of your blog and store it in the _site folder.

When all is done, the script switches to the _site folder, adds all files to the bundle, commits the changes to local Git repository and then pushes it to your Git-enabled web hosting account.

Before you can add this script to the crontab task list, you need to make it executable. In your Terminal app, go to wherever you saved your script and then type chmod a+x jekyll_script.sh and hit <Enter>.

Crontab task

This one’s fairly easy. To add the task to crontab task list do the following:

  1. Using the Terminal app, open the crontab file for editing: type crontab -e and hit <Enter>.
  2. add */15 * * * * ~/Dropbox/jekyll_script.sh >/dev/null 2>&1 to the file and save it.

Notice the */15 part? This tells the crontab that the script is to be executed every 15 minutes. You can adjust the frequency as per your needs (sometimes, waiting 15 minutes for a post to get published can be way too long a time :)).

NOTE: 

If it seems that the Git push doesn’t work, try enabling logs for the crontab by changing the line to: */15 * * * * ~/Dropbox/jekyll_script.sh > ~/Dropbox/cronlog.log

If you get a warning that there’s problem with authentication, go to the Terminal app, navigate to the ~/myblog/_site and type in: git config --global credential.helper store and hit <Enter>.

All done.

Congrats! You’ve just made use of your spare/idle Mac, which allowed you to publish onto your Jekyll-based blog no matter the device or location (for as long as you have access to your Dropbox account and your Mac runs 24/7, of course :))