How I built my blog πŸ’β€β™€οΈβœ¨

seg 28 julho 2025

Translations: pt

Having a space of my own away from social media, away from algorithms was something I’d wanted for a long time. A little corner to write about what I love, in my own way, without rushing. And that’s how my blog was born. πŸ’›

In this post, I’m sharing how I went from idea to live site from choosing the stack all the way to deploying it.

The stack I chose

I went with Pelican, a static site generator written in Python. It won me over for a few reasons:

  • It’s built with Python πŸ
  • It generates pure HTML (lightweight, fast, and easy to host)
    • Meaning: nothing is processed dynamically on the server. That makes the site faster, more secure, and cheaper/easier to host (like on GitHub Pages, which only serves static files).
  • The structure is simple to customize
  • Posts are written in Markdown πŸ“
  • The documentation… is a bit confusing, but I pushed through anyway πŸ˜…

I also used uv as my package and virtual environment manager it’s fast, practical, and has replaced my old manual venv + pip workflow.


πŸ› οΈ Step by step

1. Setting up the environment and installing Pelican

I used uv to create my virtual environment:

uv venv

Then I activated it manually:

source .venv/bin/activate

uv venv creates the environment with isolation, but doesn’t activate it automatically. I did it out of habit it’s the traditional way most of us learned with venv.

That said, uv also offers a more modern (and practical!) way to handle virtual environments. You can skip uv venv and source entirely and just let uv manage everything:

uv add pelican[markdown] # declares `pelican` as a project dependency

uv run pelican-quickstart # runs `pelican-quickstart` inside the automatically managed virtual environment

This way, uv creates the environment and runs commands inside it automatically no manual activation needed.

One note: if you prefer using uv add ... and uv run ..., you’d need to update the Makefile, replacing PELICAN=pelican with PELICAN=uv run pelican or all make <rule> calls would need to become PELICAN="uv run pelican" make <rule>.


2. Project structure

I followed the setup prompts and had a basic structure ready in no time. From there, I organized the repo with a clear focus:

  • content/ β†’ where the Markdown posts live
  • output/ β†’ the generated HTML site
  • theme/ β†’ theme files and customizations

The repository is available here: github.com/aninhasalesp/meublog

I created the pelican-themes/ folder manually to clone the theme and make my own modifications.


3. Choosing and customizing the theme πŸŽ¨

I used the notmyidea-cms theme that comes with Pelican and customized it little by little.

In pelicanconf.py:

THEME = "pelican-themes/notmyidea-cms"

The changes I made:

  • Footer with my name and a link to my GitHub β€οΈ
  • Comments with Utterances
  • Share buttons (LinkedIn, WhatsApp and Telegram)
  • CSS tweaks for spacing, layout, and colors

4. Comments with Utterances πŸ’¬

I used Utterances to enable comments on posts. It’s lightweight, uses GitHub issues, and it’s simple and efficient:

<div id="comments">
  <script src="https://utteranc.es/client.js"
    repo="aninhasalesp/meublog"
    issue-term="pathname"
    theme="github-light"
    crossorigin="anonymous"
    async>
  </script>
</div>

5. Writing posts βœοΈ

Posts live in content/ and are written like this:

Title: First post
Date: 2025-07-20
Category: personal
Summary: A short welcome text for the blog.

---

This is the first post! πŸŽ‰

6. Theme customizations

I edited files inside pelican-themes/notmyidea-cms/ to give the blog more of its own identity.

In CSS:

  • Adjusted padding and margins
  • Better alignment of elements
  • Added icons and visual links

In HTML (like base.html):

  • Added the footer
  • Positioned the share buttons

πŸ’‘ Editing the theme directly worked well for me, even if it’s not the ideal long-term approach.


7. Generating the static files

To compile the blog and generate the HTML:

make html

During development, I used the local server to preview changes:

pelican --listen

8. Deploy to GitHub Pages πŸš€

I used GitHub Pages to host the blog. The process was:

  1. Generated the files with pelican content or make html
  2. Pushed the output/ folder to the gh-pages branch
  3. Set up the custom domain on GitHub and pointed the DNS to GitHub’s servers

The Makefile made things easier, I published with:

make github

This command handles the whole thing. Here’s roughly what it does:

cd output
git checkout -b gh-pages
git add .
git commit -m "Deploy"
git push -f origin gh-pages

On GitHub, I went to Settings > Pages and:

  1. Configured it to serve the site from the gh-pages branch, root folder (/)
  2. Added a CNAME file with my custom domain (anapaula.org)
  3. Pointed the DNS from my registrar to GitHub Pages
  4. Enabled HTTPS

You can automate this with GitHub Actions too. But since this is a personal blog I don’t update every day, I preferred the manual approach.


9. Custom domain πŸŒ

I registered the anapaula.org domain and configured it for the blog hosted on GitHub Pages.

What I did: In the registrar’s panel, I added the following DNS records:

A records (IPv4): pointing to GitHub Pages’ IPs:

185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
  • CNAME (if you want a subdomain): pointing to youraccount.github.io

Inside the output/ folder (which goes to the gh-pages branch), I created a CNAME file with just:

anapaula.org

This tells GitHub which domain to link to your site. This file is included automatically in every deploy when I run make github.

On GitHub, under Settings > Pages:

  • I checked “Use a custom domain” and entered anapaula.org
  • Enabled HTTPS for secure browsing

I followed the official GitHub Pages documentation for all of this: πŸ‘‰ GitHub Pages docs


Wrapping up

The process had its bumps (Pelican’s docs could really use some love πŸ˜…), but it was totally worth it. Having a space of my own with my name, my style was a long-time wish that finally became real.

If you’re also thinking about starting a blog, whether technical or personal, I really recommend it! And if I can help in any way, just reach out. πŸ’›

The blog’s source code is on GitHub: aninhasalesp/meublog πŸŒ±

Compartilhar: LinkedIn Telegram WhatsApp