Good Bye Wordpress. Hello Hugo on Azure Storage

Good Bye Wordpress. Hello Hugo on Azure Storage

Overview

In May 2020, having realised that my role at work had stabilised a bit, I decided to get back to blogging again. I had learned so much over the years and had not really made an effort to share any of it. Not that I have a million followers waiting to read what I share. But for me, it meant, having to think about what I learned again and explain it in a way that another person can understand. An excercise in communication.

Blogging or even writing down or drawing diagrams of a proposed solution to a problem has helped me arrive at better solutions, purely because, it sometimes gives different perspectives when you think over it again. So I decided, I had to do it.

Wordpress, as we all probably know, is a very popular platform for blogging. Although many of my tech mates prefer other blogging platforms, Wordpress is not a bad place to start your blog at all. You get so much for free, until you get to the point where you want to use a custom domain or a nice theme that does not come for free. Of course you could host your own Wordpress instance on a cloud provider and still get things rolling too.

I had been so deep into management and a lot of firefighting at work that I had not taken the time to do a full dive down into alternatives to Wordpress and so I thought, I'll just give it a shot. I had some domains after all, like most of us software engineers, that I just hadn't used, until then. Got the Wordpress.com premium for USD 96.00 / year. Quite a lot of money for hosting my barely visited static content really.

But I did get an entire blog engine for free hosted at a free domain too and with a few clicks of a button, I could also import all my earlier blog posts, which I am not at all proud of, from Blogger. That to me, is amazing!

However, having spent a large part of last year, getting my hands dirty on Azure and coding a lot more frequently than I had ever done in the 2 years prior to that, I realised, I had many better alternatives for blogging about code and engineering management. I also learned that with the power of cloud, I could just host my own little blog, for much cheaper. I must admit, the initial cost of migrating is pretty high but the running cost is several times cheaper.

That's what I did with my blog from wordpress.

What did I want to do with my blog?

I wanted to write my blog posts in Markdown. That was my primary requirement. I also wanted to host it wherever I felt like depending on the cost. Although I say that, for me, I felt, if I were going to try to deploy it anywhere, I'd like to first try it on Azure. So based on my first criteria alone, Wordpress was completely out of scope.

Where did I move the blog from and where to?

As I have primarily been working on Microsoft Azure, I thought this was an opportunity to try more of Azure's features. I have previously hosted my doggy day care's website (now defunct) on Azure as a web app. That was when I had barely started out on Azure. And you can find all about the pricing of an App Service. For me it turns out to be around GBP8.00 per month.

So this time, I thought, I would do things differently. I wanted to try out how I could host a static website on Azure Blob Storage. This after having read more about the pricing details of Azure Blob Storage turned out a lot cheaper. If you don't have a front-end framework, then you are really just being charged for storage. So this seemed like the best fit for my blog as all I want to do is publish blog posts.

But first, I needed a blog engine or a static website generator.

Hugo - Static website generator

As the title of this section states, Hugo is a static website generator, i.e. a website that does not fetch any type of data from a database or backend based on user interactions.

I only happened to stumble across Hugo recently. I read some of the reviews and was impressed by everyone praising the speed of site generation and the flexibility it provides. You can actually see a performance test on the Hugo Website. It also has a whole load of themes. It is in no way a new project either. I probably never looked for it and feel like I missed out totally.

Hugo is open source and built in Go (Golang). Although I can write my posts in Markdown, I can also use some special Hugo features to make my posts look even more interesting. Hugo also comes with multi-language support built-in.

I was not expecting so much. But I tried it and I loved it. The speed especially. Now I would love to learn Golang just so that I can contribute to the project.

Enough talk, try it for yourself

It is pretty easy to get started with Hugo. You can find all the instructions to download and install it in your machine from Hugo - Getting Started - Installing. I did all of it on a windows machine and had Chocolatey already installed on my machine. So I did not have to think twice, just go ahead and install.

1choco install hugo-extended -confirm

I installed the extended version as I wanted to use a Hugo-Theme, named Hugo Clarity that required this. Extended version includes Sass and advanced CSS preprocessor support.

What do I need to know to get started?

Everything you need to know to get started is on the Hugo - Getting Started page. Once installed you will be able to run the Hugo command from your command line.

Running that in a directory with a hugo generated website will actually build the website.

Create new site

Create a site named mycoolsite in a folder of the same name in the location on disk where you ran the command.

1hugo new site mycoolsite
2

Add a theme

This is the one thing that I found a bit awkward which I think will change in the future. Themes currently are installed to your website as a git submodule. Now if you have never heard of Git submodules, do not worry. I only learned about it when I tried out Hugo.

In simple terms, Git submodules are like nested git repositories. If I use something from a repository named X in my respository named A and I would rarely make changes to the X repository and would want to use the code there but do not have a package manager to manage centralised packaged code, then I could use X as a submodule in my A repository.

This is not a popular concept because most developers use a package repository and a package manager to handle dependencies. But for now, this is the most popular way of adding themes.

1cd mycoolsite
2git init
3git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
4echo theme = \"ananke\" >> config.toml

The last step adds the key value pair:

1theme = "ananke"

to the site's config.toml file. These files can be in one of three different formats, YML or TOML or JSON.

Create a post

1hugo new posts/new-post.md

That's all it takes to create a draft post.

On top of the post page, you will find some metadata, which Hugo calls: frontmatter.

Run the server

1hugo server -D

Hugo runs a server that watches all the files in the site directory and the -D option tells Hugo to build and serve the drafts too. This renders the website every time you make changes your site. Handy when writing new posts and also useful when making changes to your theme or other content.

Build the site

1hugo

Your static website will be generated inside a public folder in your hugo site directory.

How did I host it on Azure?

To begin with I needed a plan that answered the following questions:

  • How would I get my custom domain to work there, when I originally bought it from Wordpress.com?
  • How do I import my wordpress blogs to Hugo?
  • How was I going to host it on Azure?
  • If I were writing new posts regularly, how do I automate the deployment of the site?

Those were the things that I needed answers for. Luckily, I was not the first person hosting a static website on Azure. The year is 2021, so surely, thousands have done it before me.

As I go through the steps, I will cover some of the high level concepts of the tech I used.

Domain: Where I got it and how I transferred it?

I have been a Namecheap customer for a pretty long time and have only good things to say about them.

So the first thing I did was try and transfer my domain from Wordpress.com to namecheap using Namecheap's Easy Domain Transfer. Domain transfer, just like a phone number porting, requires you to provide an authcode from the current registrar. This I could get easily by initiating a domain transfer request on Wordpress. You can find this under a url like wordpress.com/domains/manage where you'll get a page with your domains and options. You can read the official wordpress docs on transferring your domain. This is a really straightforward process.

How did I import my old blog to Hugo?

Hugo has an entire page dedicated to Migration.

I personally used and contributed to Blog2Md, a nifty javascript tool to read a blogger/wordpress backup xml and convert it into markdown posts.

Azure storage and static website hosting

Anyone using Azure can create a storage account where you can host a website. Azure Blob Storage is an object storage solution, where you store all sorts of unstructured data and serve these directly to a browser or to a REST API, or consume in many other ways.

To start using Azure Blob Storage, you need to understand that there are three types of resources to it.

  • Storage Account
  • Containers
  • Blob

Storage Accounts

A namespace in Azure for your data.

Containers

A grouping of a set of blob, similar to a directory in a file system.

Blobs

These are your Data. There are subcategories to this, but you don't know need to know that to host a website.

Instructions on Azure Hosting

First follow the instructions to create a storage account.

As of this writing, General Purpose V2 storage account is the latest of the cheapest. You can read all about the special features in the official documentation

In order to host your website on Azure Storage, you have to enable the feature on the storage account.

Follow directions to Host a static Website in Azure Storage

You might find Azure Storage Explorer useful if you are going to test copying files over to the blob storage. Download, install and sign-in to have a local version of the storage explorer that you could otherwise view on Azure Portal.

Once you have done this, you probably want to map your fancy domain name to your blog. Currently you can map HTTP only traffic directly following instructions on map a custom domain to your azure blob storage endpoint.

Azure CDN

Content Delivery Networks are a geographically distributed group of servers which work together to provide fast delivery of internet content. A CDN allows you to serve content from a place closest to your user. Although they are great when it comes to caching content to help your website's performance, they are not a replacement for your regular hosting server. They work in addition to your webserver.

Thus in the case of a static website, Azure CDN is great for caching static objects loaded from Azure blob storage, a web application or any publicly accessible web server. You can read more about Azure CDN on the official documentation.

For HTTPS, Azure recommends using CDN, follow instructions to map a custom domain with HTTPS enabled

I personally did the HTTPS configuration as you can already see if you are reading this post on my blog.

Automation using Github Actions and AZ CLI

In order to automate this process, I needed to host my static website code in a github repository. You can read all about how to create a new repository from the official github - create a repo documentation. Then make use of Github's continuous integration and deployment tools, which they collectively call Github Actions.

Github Actions

If you have used a CI/CD tool previously, you will find it relatively easy to understand github actions. The idea is to help users automate tasks within your software development life cycle. Some concepts that build this up are:

Events

An action or set of actions are always triggered by an event, like a push or a pull request completion, etc.

Jobs

Several steps make up a job. By default, if there are multiple jobs in a workflow, they are executed in parallel, however, this can be configured to run in sequence.

Workflows

Several jobs make a workflow. A workflow could also be just one job.

Steps

Events trigger a series of steps, each of which comprise one or many actions that perform certain specific things. Every step in a job runs in the same runner in sequence.

Actions

Standalone commands, the atomic units or building blocks of steps

Runners

A server that has the GitHub actions runner app installed and is responsible for running your workflows.

You can read all this in detail in the official GitHub Documentation to learn Github Actions

How do I define workflows?

They are generally written in YAML. They generally live inside your repository under .github/workflows/main.yml

Before you go ahead and do that you have to configure some credentials to enable your github workflow to perform actions on your azure storage account. Configure this using the Azure Login Action Instructions.

I would also define the following secrets on your repository, you can pick names of your choice, I just went with the following:

  • AZURE_BLOG_RESOURCE_GROUP - name of the resource group under which you have your storage account
  • AZURE_BLOG_SUBSCRIPTION_NAME - name of the azure subscription
  • AZURE_CDN_ENDPOINT - name of the CDN endpoint
  • AZURE_CDN_PROFILE_NAME - name of the CDN profile that has your endpoint
  • AZURE_CREDENTIALS - generated earlier following Azure login action instructions
  • AZURE_STORAGE_CONNECTION_STRING - Read how to retrieve this

This will make your action file safe to share as all your secrets are encrypted and stored safely in Github, making the workflow totally shareable, hence, I have created a public gist to share it with you below, embedded here using Hugo Shortcodes, another one of those cool features that make Hugo awesome.

Now when I commit this post and merge it to my main branch, I get the entire site deployed and rendered.

I hope that helped you. If you have questions, feel free to comment here.

comments powered by Disqus