Building This Blog: Jekyll on GitHub Pages from Zero to 130 Posts

ankitg121 pts0 comments

Building This Blog: Jekyll on GitHub Pages from Zero to 130+ Posts | McGarrah Technical Blog

Engineering deep dives on infrastructure, distributed systems, and AI/ML — from homelab experiments to enterprise architecture.

I’ve been writing about technology since 2004 — first on WordPress, then Blogger, and now Jekyll on GitHub Pages. The migration to Jekyll happened in 2023 when I wanted full control over the site without paying for hosting or fighting with WordPress plugin conflicts.

Two years and 130+ posts later, the blog has grown from a basic theme into a heavily customized platform with Mermaid diagrams, GDPR compliance, Pandoc PDF exports, and an automated SEO pipeline. This post covers how I set it all up — the order of operations, the decisions I made, and what I’d do differently.

For the day-to-day writing reference (markdown syntax, code blocks, diagrams, embeds), see the companion post: How the Sausage Is Made: Every Feature Powering This Jekyll Blog.

Why Jekyll?

After years on WordPress, I wanted:

No hosting costs — GitHub Pages is free

Version control — every post is a Git commit with full history

Markdown — write in a text editor, not a web form

Speed — static HTML is fast, no database queries

Control — no plugin conflicts, no PHP updates, no security patches

The tradeoff is that Jekyll requires comfort with the command line, Git, and Ruby. If you’re reading this blog, you probably have that.

Create the GitHub Pages Repository

GitHub Pages serves a static site from any repository named .github.io. Create the repo, clone it, and you have a working site:

git clone git@github.com:/.github.io.git<br>cd .github.io

GitHub automatically builds and serves anything pushed to the default branch at https://.github.io.

Pick a Theme

Rather than starting from a blank index.html, pick a Jekyll theme. This blog uses the Contrast theme by Niklas Buschmann — minimal, responsive, and easy to extend. I’ve since modified it heavily, but the bones are still Contrast.

The fastest way to start:

Fork or copy the theme repository into your .github.io repo

Run bundle install to pull dependencies

Run bundle exec jekyll serve to preview locally at http://localhost:4000

gem install bundler jekyll<br>bundle install<br>bundle exec jekyll serve

See Running GitHub Pages Jekyll Locally for the full local development setup including Ruby version management.

Initial Configuration

The _config.yml file controls everything. The essential settings to change immediately:

title: "Your Site Title"<br>description: "A brief description for SEO and social sharing"<br>url: "https://www.yourdomain.com"<br>author:<br>name: "Your Name"<br>email: "you@example.com"

plugins:<br>- jekyll-feed # RSS feed<br>- jekyll-sitemap # XML sitemap for search engines<br>- jekyll-paginate # Post pagination<br>- jekyll-seo-tag # SEO meta tags and structured data<br>- jekyll-redirect-from # Redirect support for moved pages

Changes to _config.yml require restarting jekyll serve — it’s not hot-reloaded like post content.

File Structure

After theme setup, the key files:

├── _config.yml # Site configuration<br>├── _layouts/ # Page templates (default, post, page)<br>├── _includes/ # Reusable HTML components<br>├── _sass/ # SCSS stylesheets<br>├── _posts/ # Published articles (YYYY-MM-DD-title.md)<br>├── _drafts/ # Work-in-progress (no date prefix)<br>├── _plugins/ # Custom Ruby plugins<br>├── assets/ # CSS, JS, images, fonts<br>├── Gemfile # Ruby dependencies<br>├── CNAME # Custom domain mapping<br>└── index.html # Homepage

Custom Domain

To serve the site from a custom domain instead of .github.io:

Create a CNAME file in the repository root with your apex domain (no www):

mcgarrah.org

Configure DNS with your registrar:

A records for the apex domain (@) pointing to GitHub Pages IPs:

185.199.108.153

185.199.109.153

185.199.110.153

185.199.111.153

CNAME record for www pointing to .github.io

In the GitHub repository settings under Pages, set the custom domain to the apex domain (e.g., mcgarrah.org) and enable Enforce HTTPS

GitHub handles the Let’s Encrypt certificate automatically. With this configuration, GitHub Pages serves the site from the apex domain and automatically 301-redirects www to the apex.

The GitHub Pages custom domain docs cover the full DNS setup.

I’m currently migrating my domains from Squarespace to Porkbun for better API access and lower costs — relevant if you’re choosing a registrar for a new blog.

The www vs Apex Domain Trap

I ran into a subtle but damaging SEO issue that’s worth documenting. My original CNAME file was set to www.mcgarrah.org, but my _config.yml had:

url: "https://mcgarrah.org"

This created a mismatch across the entire site:

Component<br>Domain Used

CNAME (GitHub Pages primary)<br>www.mcgarrah.org

_config.yml url<br>mcgarrah.org

jekyll-seo-tag canonical URLs<br>mcgarrah.org

jekyll-sitemap URLs<br>mcgarrah.org

robots.txt sitemap reference<br>mcgarrah.org

GitHub Pages treated www.mcgarrah.org as the primary domain and 301-redirected the apex mcgarrah.org →...

github jekyll pages mcgarrah domain from

Related Articles