Creating a blog using GitHub Pages
Many software engineers have blogs, whether it’s to write about a particularly sticky problem they ran into, express their opinion about a given technology, evangelize their own projects, or to create a tutorial for a common task. This article falls into the latter category, as I felt like there are so many options with varying levels of barrier to entry, but there’s a really simple solution.
This blog was originally hosted on a WordPress site which shared an Azure App Service with some other websites I have and it’s own MySql database. Now not only did that cost money (or would have if it wasn’t sharing existing resources), but it was just way overkill for what I was doing, and even for all that it was just plain slow. Furthermore, and this is possibly just personal preference, I really just wanted to write Markdown and not have to deal with a fancy text editor or raw HTML. WordPress may be OK for people who don’t want to deal with any sort of programming or configuration but I, and I suspect most programmers, are more comfortable working with some sort of markup language like Markdown.
After looking around, I ended up landing on GitHub Pages. In essence, GitHub Pages allows you to host static web content for free. They also provide integration with Jekyll, a static content generator, which gives a little bit more flexibility. For those not familiar with static content generation, it’s basically just a tool which transforms some content and configuration into a full website. This allows you to create templates, shared includes, and variables to avoid having to write and update full HTML pages. GitHub Pages is also really easy to set up as it’s just a special GitHub repo, and it’s blazingly fast since your content is extremely cacheable so is generally served from CDN.
Assuming I’ve sold you on GitHub Pages, let’s see how easy it is to set up. There is documentation for both GitHub pages and Jekyll, but in my opinion the docs can be a bit hard to navigate since it’s split across the two sites and many of Jekyll’s features are not available on GitHub pages, which is unclear from the docs. This guide intends to explain the basics, as well as some of the more advanced topics I found useful. You can also see this blog’s repo for reference when configuring your own blog.
GitHub Pages allows a user, organization, or even a project to have its own site. For user sites, it’s in is own repo. The GitHub Pages website gives step-by-step instructions, but really all you have to do is create a repo named .github.io .
After the repo is created, clone it locally and clear out the initial boilerplate GitHub gives you.
Setting up WSL
(Users not using Windows can skip this section)
Unfortunately, Windows is not officially supported by Jekyll. They provide some workarounds, but personally it seemed more trouble than it’s worth. Because of this, I recommend using the Windows Subsystem for Linux, or WSL.
First, ensure CPU Virtualization is enabled in the BIOS. The process for enabling it varies by manufacturer, but you can check whether it’s enabled in the Task Manager under the performance tab.
Next, you’ll need to actually install WSL 2. Follow the official instructions for a step-by-step guide. Personally, I ended up using the Ubuntu 20.04 distro, but you should be able to use whichever you prefer.
Jekyll requires Ruby, so you’ll first need to install it. On Ubuntu, just run:
From your Linux shell, navigate to your GitHub repository created earlier and run:
Note that for Windows users, your Windows drives like C: are mounted in WSL, so you can get to a path like C:\Users\David\Code\dfederm.github.io via /mnt/c/Users/David/Code/dfederm.github.io .
The new Jekyll template is a good starting point, but you’ll want to make a few changes to work properly with GitHub Pages.
From here on you can edit the files in your favorite editor, eg. Visual Studio Code. You only need to use your Linux shell to run ruby, bundle, and Jekyll commands.
First, replace the Gemfile contents with the following:
You’ll notice that the github-pages gem is there, which ensures what you’re using locally matches what GitHub Pages uses. Notably GitHub pages does not support arbitrary Jekyll plugins, so you generally shouldn’t deviate from this Gemfile too much. The list of Jekyll plugins and other Ruby Gems GitHub pages supports can be found on their website.
After updating the Gemfile , you’ll want to bundle update to install everything.
To build the site and serve it locally, run:
For those running Windows, I recommend adding –force_polling . Otherwise, saving your content sometimes does not auto-regenerate the site.
Your site should now be running at http://localhost:4000 !
For the curious, you can see the entire generated website under the _site folder.
Once you commit and push your changes, GitHub will automatically build your website and deploy it within minutes. Your website will be at .github.io . You’re up and running!
Jekyll is quite powerful and the docs go into details about every feature. Below I’ll describe the major ones which will get you up and running.
Configuring the site
_config.yml is the primary configuration for the site as a whole. It describes how to build the site, site-wide configuration, and custom site-wide variables you may want to define.
The new site template hits a few of the major configurations, however I’d recommend adding a few more:
To describe these settings:
is the url format for your permalinks. I like the url to just be the post title.
- markdown is the markdown formatter.
- paginate is the number of posts per page if using pagination. (requires the jekyll-paginate plugin)
- paginate_path is the url format for pages. I like a simple /1 , /2 , etc. (requires the jekyll-paginate plugin)
- date_format is the default date format the site uses.
GitHub Pages also forces some configuration which you cannot change. Be sure to avoid changing these or you’ll only see the behavior locally and they’ll be lost when deployed.
This is also where you configure your plugins, for example:
To describe these plugins:
creates an Atom feed for your site at /feed.xml . enables pagination adds search engine metadata to the site. creates a site map for your site at /sitemap.xml .
You can also add any other custom various in this file as well. Simply add them to the _config.yml file, for example:
These custom variables can be used in your content like > .
These are for standalone content for your site, like the home page, about page, contact page, etc. These can be either .html or .md files, based on whichever is better for writing your content.
By default, the url for pages follows the folder structure you use, so documentation\doc1.md would become /documentation/doc1.html , but this can be overridden.
Front Matter, Layouts, and Includes
Jekyll is a templating engine, which helps avoid duplication and enable you to express what you want to happen rather than having to type it up by hand.
“Front Matter” is a term for a file that contains a YAML block at the top of the file and is processed by Jekyll. The YAML must be set between triple-dashed lines and is where you define the file-specific variables. For example, you can specify the layout for Jekyll to use, the title, and custom variables to use within the page.
An example from my About page:
Layouts are basically the template for the content. There are some default layouts, but you’ll likely want to customize your own. Layouts reside under the _layouts folder and the layout name is just the file name without extension. In the example above for my about page, I have the layout at _layouts\page.html .
A layout may inherit other layouts (and in fact, my page layout inherits my default layout), and specifies where to put the file’s content with > .
Finally, includes can be used to insert files into the current file without having to repeat it. It can also help organize your content and layouts by extracting logical blocks into separate files.
To put it all together, for my site I have something like the following files (simplified for brevity, and omitted some files):