Build-A-Blog Part 1
Build-A-Blog Part 1
Starting a blog can be a bit scary; you’ve got to put yourself out there and take a chance that you actually know what you’re talking about. I’m sure there’s going to be issues and mistakes with what I post, so please let me know if you catch anything!
Here’s my thought process and configuration work behind this blog.
CMS or Static Site
The first decision was how I wanted to host my site; a Content Management System (CMS) like Wordpress, or a Static Site Generator (SSG) like Hugo. If you’re not familiar with the difference on these, it’s pretty simple; a CMS is a platform that dynamically generates your website whenever someone accesses it based on content and configuration stored in a connected database, while an SSG is pre-compiled into HTML from your code base, and that pre-compiled HTML is served whenever someone access the site.
CMS platforms have huge user bases, which means there’s tons of support available online, as well as tons of plugins and themes. There are also tons of security issues, especially if you’re not regularly updating (or your plugins are not regularly updated). CMS platforms are also much easier to use; posts are created in WYSIWYG editors, configuration is done through GUI dashboards, and there’s little to no reason to use the command line.
SSG’s are becoming more and more popular because they solve several of the issues with CMS platforms, most notably security. However, because they’re not dynamic there’s simply some things you can’t do with them like mailing lists, e-commerce, or comment sections. Also, if you have non-technical people creating content, the code-style background may put them off. Fixes for all of those issues are becoming available, however, with graphical front-ends like Forestry and external plugins for dynamic applications. Also, and very importantly, SSG’s are much faster than CMS platforms because they’re pre-compiled. CMS platforms are building sites on the fly, so require much more computing power to equal the speed of SSG’s.
Since one of my goals is #Programming, and since I like the security aspects, I decided to go with an SSG. There are a lot of them, but a little research showed that one of the top picks, Hugo, is based on one of the languages I’ve been learning (Go) so I was already familiar with the templating.
Code Repository
I’ve been learning Git and it seems like a great fit for this project (mostly because I don’t know much about other versioning systems). About a year ago I looked into self-hosting my repository with gitea and GitLab. They both worked fairly well; gitea was a much lighter solution than GitLab, but GitLab offered a lot more functionality (some behind a paywall). I had them both installed at times, but ended up using gitea for a while. Sometime since then, GitLab made their CI/CD pipeline part of their free tier, so I decided to move everything over. CI/CD is something I definitely want to learn, and this looked like a great opportunity. Instead of self-hosting GitLab, I went with their free tier on GitLab.com for now as it’s much easier to test out their capabilities this way. I set up a personal account and a group for my homelab projects.
Website: Self Hosted or Cloud
One of my stretch goals is to get familiar with Amazon or Google hosting, but I didn’t want to start that yet. But GitLab.com does offer a nice middle step; GitLab Pages. Pages allows you to host a static website from a GitLab.com repository while taking full advantage of their CI/CD pipeline.
Set Up a Hugo Project With GitLab Pages
Here I’ll describe all the steps I took to get this blog up and running. The goal for this post is to create a static Hugo website that’s reachable from a personal domain name (homelab.flora.family). We’ll work on the site theme, customization, and content in the next post.
Create the Project in GitLab
Normally we’d start by initializing a code repository on our local workstation. However, GitLab.com offers pre-built templates for many types of projects (including Hugo) with the CI/CD pipeline already configured. So for our purposes, it’s actually easier to start in Gitlab.com.
The first step is to create the project with the Hugo template. Here I’ve logged into my GitLab.com account and opened my Group page “Flora HomeLab”. Click on the New Project button.

From the New Project page, click into the Create from template tab and scroll down to the Pages/Hugo template. Click the Use template button to the right.
Choose a name for your project (which will show in the GitLab menus). A project slug will be generated from your name, but feel free to choose your own. This will be the name of the git directory and will be in the gitlab.io website URL. My group is set to ‘private’, so that’s the only option for me. If you want anyone to be able to access your group, feel free to change this.

Give it a minute to set up, and you should see something like this:

Set up GitLab Pages
Now that the code repository is ready, let’s set it up with GitLab Pages.
The URL for my repository was initially http://flora-homelab.gitlab.io/homelab-website. That’s my group path (flora-homelab) at the front and the project slug (homelab-website) at the end. You can pull it up now, but you’ll get an HTTP 401: Unauthorized error. There’s a perfectly reasonable explanation; we’ve set up the code repository, but we haven’t deployed it yet. To do that, we simply have to kick off our CI/CD pipeline.
From the project page, hover over the CI/CD link in the left sidebar and click Pipelines in the menu. Click the Run Pipeline button near the top right corner.

And again click the Run Pipeline button in the screen that opens. Then you’ll see your pipeline going.

GitLab is now running your deploy pipeline on their community runners. At the time of writing, GitLab provides free access to their shared runners for public open source projects, and limits them to 2000 minutes per group for other projects. 2000 minutes is a lot for Hugo, which is just a blazingly fast SSG. But if it looks like you’re going to run out, it’s super easy to configure your own GitLab runner and it’s exactly the sort of thing a responsible homelabber would do. I’ll discuss that in a future post.
The pipeline will take a few minutes to complete on the shared runners (most of it is just waiting in the queue), but once complete you should be able to see the bare template! Mine was at https://flora-homelab.gitlab.io/homelab-website.

Customize With Your Personal Domain
The page is looking great, but the URL sure is ugly. Let’s configure this with our own domain.
While there’s a lot of expensive Top Level Domains (TLD’s), there are a ton of very inexpensive ones. My flora.family domain costs about $20/year, but you can get domains much cheaper than that. In order to set this up, you’ll need a domain registrar that controls the DNS for your domain. There are a million ways to do this; I use Namecheap.
The first step is to get the info we’ll need from GitLab. From your main project screen, hover over Settings in the left sidebar, and select Pages in the sub-menu. On that page, click the New Domain button in the top right corner.

I want to reach my page at homelab.flora.family, so that’s what I put in the Domain field. We also only want to enable access to this site via secure HTTP (HTTPS), so make sure the Let’s Encrypt option is checked (which is the default). Click the Create New Domain button in the bottom left. That opens the Pages Domain page which gives us the information we’ll need to configure our DNS. Leave this page open as we’ll need this info in the next step.

These two records accomplish two very important things. First, with the CNAME record, we’re telling Namecheap that whenever someone goes to homelab.flora.family, we want to redirect them over to flora-family.gitlab.io. Second, we’re making a TXT record available so that GitLab can authenticate our DNS setup; anybody could spoof a packet from our domain to GitLab, but only someone with access to both our Namecheap and GitLab admin pages can set up that TXT record.
I use NameCheap for all my DNS needs, so I log in there, click the Manage button beside my domain, and then click into the Advanced DNS tab. From here we can create the Host Records that GitLab needs. Back on the Pages Domain page in GitLab, we’ll start with the setting labelled DNS that includes a CNAME tag. The format of this information is how you’d enter it into a CLI domain service like BIND, so we’re going to pick what we need from this.
In NameCheap, we’re going to click Add New Record, choose type CNAME Record. For the Host field in NameCheap, we want the first word of the first part of the GitLab line, (in my case, just the word homelab from homelab.flora.family; Namecheap already knows it’s for flora.family). And for the Value field in NameCheap, we want the last part of the GitLab line (flora-family.gitlab.io.).
NOTE: Do not leave off that trailing period. Some DNS registrars don’t care if it’s there, but some do and it won’t point correctly to your GitLab Pages site. Why? I have no clue, just learned that the hard way.
Next we’ll enter the TXT record listed under the Verification Status section on the Pages Domain page. Again, we’re going to pick what we need from this line. In NameCheap, we’re going to click Add New Record, choose type TXT Record. For the Host field in NameCheap, we want the first *two words of the first part of the GitLab line, (in my case, _gitlab-pages-verification-code.homelab). And for the Value field in NameCheap, we want the last part of the GitLab line (gitlab-pages-verification-code=*32letters&numbers*).
After those two records are entered, here’s what my NameCheap setup looks like

Now, feel free to try clicking the retry button beside the Unverified label in the middle of the GitLab Pages Domain page. But don’t be worried if it doesn’t work immediately! It can take up to an hour or more for your DNS changes to propagate. Just take a break, get a snack, play with your dog (if applicable), and come back. If it’s still not working the next day, then there’s definitely a problem somewhere. One time I forgot to save the record in NameCheap, another time I didn’t have the underscore at the very front, and yet another time I finally realized that I didn’t copy all of the letters in the TXT record. I’ve always seen 32 letters & numbers in that code, but GitLab could certainly change that at any time.
Once GitLab has verified your DNS settings, it will automatically request a security certificate from Let’s Encrypt. If you’re not familiar with them, they are an amazing organization that offers security certificates for free that are accepted by all major browsers. This means we can lock our website access down with HTTPS. As with the verification, getting your security certificates can take an hour or more, and if you don’t have them in 24 hours there’s likely a problem. I don’t know what I did wrong the first time, but the resolution I found was to remove the Page Domain configuration in GitLab completely and redo this part of the process. Just remember that the second time through, your TXT record will change so make sure to update it in NameCheap.
Once you’ve received your Let’s Encrypt certificate, make sure to check the Force HTTPS checkbox on the Pages settings page. This will ensure that anyone going to homelab.flora.family (which is the non-secure http:// version) will get automatically redirected to https://homelab.flora.family.
Configure the GitLab SSH Key
OK, now we have GitLab pages configured to serve our website on our chosen domain name, and the CI/CD pipeline will automatically test and deploy our website whenever we push changes. All that’s left is to clone the remote GitLab repository to our local machine so we can start, you know, actually developing!
There’s just one little thing we need to do first; we need to upload our SSH public key from our local machine to our GitLab profile so that we don’t have to enter our username and password every time we push code up to the remote.
If you already have an SSH key configured, just copy it to the clipboard and head to the next paragraph. If you don’t, you’ll just need to head to your terminal. From your home directory, go to your SSH directory (typically ~/.ssh) and print out the contents of id_rsa.pub. Copy that entire line to your clipboard. I’ve blacked it out in the screenshot below, but it should contain a few lines of letters, numbers, and other characters.
NOTE: Do not leave off the .pub and print out the contents of id_rsa. That’s your private key, which you should never share with anyone.

Now we go back to GitLab.com, click on our avatar icon in the far top right, and click Settings in the sub-menu. On the User Settings page in the left sidebar, click on SSH Keys. On that page, paste your SSH key in the Key dialog box, and give it a name in the Title field (this should include the user name and machine name that the key is from; the user@machine format at the end of the key works perfectly). Click the Add Key button at the bottom.
You will need to do this for every computer that you plan to code from. For instance, I have a key for my main workstation, one for my laptop, and one for my wife’s laptop that I ‘borrow’ occasionally.
Can We Actually Start Coding Now?
The last thing we need to do in GitLab.com is to get the link we need to connect our local git with the GitLab remote repository. Head back to the Project Overview and click the Clone button in the top right corner. There will be two options there: Clone with SSH and Clone with HTTPS. Copy the link for the SSH option.
I prefer the SSH method because it uses the SSH public/private key authentication method. The HTTPS method uses usernames and passwords which you have to either enter every time you push or pull code, or set them up in the gitlab configuration. The SSH key method just seems cleaner to me.
Now, assuming that you have Git installed, we’re ready to set up the local repository! From your terminal, go to whatever directory you want to keep your projects in. I personally like to keep my coding projects separated by language, so I go to ~/code/hugo. Then just type git clone and paste in your SSH link. This will create a folder named after your project slug (home in my case). Enter that directory to see your new hugo project!
Join me in Build-A-Blog Part 2 to see how I set up a new theme in my project and started customizing it!
As always, let me know if you have any questions! For now you can reach me at christopher@flora.family; hopefully I’ll have figured out how to implement a comments section for the next post in this series….