Hello World: Building This Blog
How this blog is built and deployed - Jekyll, Chirpy, GitHub Pages, and a simple workflow.
Every blog needs an obligatory first post about itself. This is that post.
The Stack
The site runs on a pretty straightforward setup:
| Layer | Tool |
|---|---|
| Static site generator | Jekyll |
| Theme | Chirpy |
| Hosting | GitHub Pages |
| CI/CD | GitHub Actions |
| Writing | Markdown + VS Code |
The Chirpy theme does a lot of heavy lifting: dark mode, table of contents, syntax highlighting, categories, tags, and search all work out of the box.
Site Structure
The repo has a slightly unconventional layout. The root serves a custom landing page, and the blog lives in a /blog subdirectory:
1
2
3
4
5
6
7
8
9
.
├── index.html # Landing page at /
├── styles.css # Landing page styles
├── assets/ # Shared assets
├── blog/ # Jekyll blog at /blog
│ ├── _config.yml
│ ├── _posts/
│ └── ...
└── .github/workflows/deploy.yml
This means gregstengel.com shows a simple homepage, and gregstengel.com/blog is where the writing lives.
The Pagination Problem
This subdirectory setup broke Chirpy’s default home page. Posts appeared in archives, categories, and tags, but the main blog index was empty except for a ghost card that went nowhere.
The culprit: Jekyll’s jekyll-paginate plugin doesn’t play well with subdirectories. The home layout relies on paginator.posts which returned malformed data in this setup.
The fix was simple - replace the pagination logic in _layouts/home.html with a direct loop through site.posts:
1
2
3
4
5
6
7
8
9
10
{% assign pinned = site.posts | where: 'pin', 'true' %}
{% assign normal = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %}
{% for post in pinned %}
<!-- render post card -->
{% endfor %}
{% for post in normal %}
<!-- render post card -->
{% endfor %}
No pagination means all posts render on one page. That’s fine for now - I can revisit when I have enough posts to need multiple pages.
The Workflow
The publishing process is about as simple as it gets:
- Write a post in
blog/_posts/ - Commit and push to
main - GitHub Actions builds the site and deploys to
gh-pages
No local Jekyll environment needed for quick posts. For previewing, I can spin up Jekyll locally, but most of the time I just push and let the automation handle it.
1
2
3
git add .
git commit -m "New post: whatever"
git push origin main
A minute later, it’s live.
What to Expect
This blog will mostly cover homelab projects, cloud architecture (AWS primarily, some GCP and Azure), automation, and whatever else I’m tinkering with. Some posts will be polished, some will be quick notes for future-me.
A number of posts here are co-written with Claude. When that’s the case, I’ll note it in the authorship. It’s a useful forcing function for documenting what I’m actually doing as I’m doing it.
Let’s see where this goes.
This post was co-written with Claude, who also happens to be helping me set up the AI assistant that will be the subject of the next several posts.