As a regular reader of this blog you may have noticed, that within the last months, a lot of change happened. I got tired of maintaining a full-blown CMS, called WordPress, just to publish my blog posts. Yes, there is a huge community around WordPress and a lot of great plugins available, but on the other hand, there is a huge attack surface to maintain. I was looking for a more efficient setup to meet my requirements. After a few experiments, this site is now built with Hugo, Cloudflare and Love.
I have started my journey with a small set of design goals:
- Improve page speed
- Preserve permalinks from WordPress
- Less maintenance overhead
- Less attack surface
As things stand today, I can consider all my goals achieved.
Setup
After a few experiments, I was pretty sure that a static page generated with Hugo was the right solution. Since I have always been very satisfied with Cloudflare’s services, Cloudflare Pages seemed to be a good choice for hosting. Further tests confirmed my assumption.
Hugo
The first thing I looked for was the right theme. I like clean styles and may be one of the last IT people who prefers bright colors. I ended up with the Stack Theme and was quite happy with the Hugo Theme Stack Starter Template which gave me a ramp-on into the Hugo universe.
GitHub Repository
I use a private GitHub repository generated from the Hugo Theme Stack Starter Template. The reason the repo is set to private is simply because my post drafts tend to be very messy.
Both workflows included in the template are quite useful. The Update-Theme workflow is almost identical in use. After some minor tweaking, the Deploy workflow also fits my needs but is now disabled and I use a different method for deployment.
Deploy workflow
|
|
Update-Theme workflow
|
|
Local Environment
Thanks to the great stack in the backend, the local environment can be any markedown editor. I prefer to work on my Ubuntu 24.04 LTS with VSCode (with markdownlint Extension)as a Markedown Editor / Preview tool. A local Hugo server is very useful, especially for configuration changes or Theme modifications.
To install the extended edition of Hugo on Ubuntu 24.04:
|
|
The Hugo snap package is strictly confined. Strictly confined snaps run in complete isolation, up to a minimal access level that’s deemed always safe. The sites you create and build must be located within your home directory, or on removable media.
Devcontainer and GitHub Codesapces
As an alternative to the local development, I increasingly use devcontainers or even GitHub Codesapces. This configuration has proven to be simple and efficient for my Hugo-Based Page:
|
|
Even the portforwarding for hugo server
(Live Preview) works fine!
Cloudflare Pages
With Cloudflare Pages, you can create full-stack applications that are instantly deployed to the Cloudflare global network. Cloudflare Pages are available on all plans.
Cloudflare provides the ability for the Hugo Framework to stage versions in different environments.
The Page for this Blog is connected to the private GitHub repository mentioned above.
To be notified about project updates I have configured a simple Email Notification. This notification is also triggered when the Hugo Theme is updated by the GitHub workflow schedule mentioned above.
Cloudflare Speed, Caching and Security
A good starting point is enabling the Cloudflare basic features for your website.
But Cloudflare offers even in the free plan way more Speed, Caching and Security features.
A great example is the “Hotlink Protection” feature, which in my case results in almost 300 blocks per day:
When Cloudflare receives an image request for your site, we check to ensure the request did not originate from visitors on another site. Visitors to your domain will still be able to download and view images.
Technically, this means that Hotlink Protection denies access to requests when the HTTP referer does not include your website domain name (and is not blank).
Hotlink protection has no impact on crawling, but it will prevent the images from being displayed on sites such as Google images, Pinterest, and Facebook.
Source: https://developers.cloudflare.com/waf/tools/scrape-shield/hotlink-protection/
The speed and caching mechanism combined with the static content results in a huge improvement in overall page speed and therefore user experience.
Cloudflare SSL/TLS
Cloudflare’s default offering, a managed universal certificate for mycloudrevolution.com, *.mycloudrevolution.com works pretty well for me.
SSL Labs attest an A+ rating for these settings:
Deployment
Production branch
Commits (or a pull request merge) to the main branch will automatically trigger deployments to the Production environment.
Note: Using only triggered deployments can be a problem if you plan to schedule posts. Hugo does not build future posts by default, hugo --buildFuture
forces Hugo to build future posts, too. For scheduled posts, a GitHub action with a cron schedule might be a better fit.
Preview branch
All commits to non-production (!main) branches will automatically trigger deployments to the Preview environment. For each commit is a preview version available:
For GitHub Pull Request even a comment with the referencing preview version is triggered:
WordPress Migration
The most challenging step was migrating my content from WordPress to markdown. None of the standard export functions were satisfying. Finally, I ended up with the wordpress-export-to-markdown tool.
This tool uses a WordPress export file as input to scrape the content of the running site.
The result required only minimal editing and tweaking, such as adding aliases, categories, and tags to the post metadata.
Metadata example with aliases, categories, and tags:
|
|
Summary
The solution of Hugo, Cloudflare and a private GitHub repository is a perfect fit for my needs. As of today, I can say that all my goals have been met, and my annual costs have been dramatically reduced to less than $10.