This not only documents the making of this website, but will also help in setting up any Hugo static site with self hosting.

Ok but why these technologies?

Mainly, Caddy is used because it’s dead simple to set up and handles SSL automatically. The GitHub actions auto deployment will allow you to have this as a private repo as well. All serving to a public domain over https.

Tech Used

  • Caddy (Serving & SSL)
  • Hugo (Static site generation)
  • VPS (for self hosting)

Recommended

  • A VPS
  • A domain

Hugo

Get Hugo installed onto both your dev machine and your server. It is important to note that some distro’s (like Ubuntu/Debian) may have very old versions of Hugo within their repo. In such cases, you can install Hugo manually from the Github.

GitHub Setup + Hugo

If you already have a github repo ready for your website, you can create a hugo site on top of it using:

hugo new site <repo name> --force

--force is used here because the folder is not empty. For example, it’s already a git repo folder.

Theme

At the time of writing, this website uses the hello-friend-ng theme. This can be installed using:

git clone https://github.com/rhazdon/hugo-theme-hello-friend-ng.git themes/hello-friend-ng

Then you need to let git know about the submodule.

git submodule add https://github.com/rhazdon/hugo-theme-hello-friend-ng.git themes/hello-friend-ng

Within your config.toml, you can set theme = "hello-friend-ng" to activate the theme.

My site configs are as follows:

baseurl      = "https://foreveranapple.com"
title        = "Dave's Learnings"
languageCode = "en-us"
theme        = "hello-friend-ng"
paginate     = 10

[params]
  dateform        = "Sep 3, 2022"
  dateformShort   = "Sep 3"
  dateformNum     = "2022-09-03"
  dateformNumTime = "2022-09-03 15:04"

  # Subtitle for home
  homeSubtitle = "Don't make my mistakes."

  # Set disableReadOtherPosts to true in order to hide the links to other posts.
  disableReadOtherPosts = false

  # Enable sharing buttons, if you like
  enableSharingButtons = true

  # Metadata mostly used in document's head
  description = "Dave's learnings."
  keywords = "homepage, blog, tech"
  images = [""]

[taxonomies]
    category = "blog"
    tag      = "tags"
    series   = "series"

[languages]
  [languages.en]
    title = "Dave's Learnings"
    subtitle = "Don't make my mistakes."
    keywords = "blog, tech"
    copyright = '<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
    readOtherPosts = "Read other posts"

    [languages.en.params.logo]
      logoText = "Dave's Learnings"
      logoHomeLink = "/"

  [[menu.main]]
    identifier = "blog"
    name       = "Blog"
    url        = "/posts"

Finally, you can add a new blog post using:

hugo new posts/my-first-post.md

Make sure you check everything with:

hugo serve -D

Deployment

Now, let’s serve it. We’ll use Caddy to serve our static files and handle SSL automatically.

Install Caddy on your server, then update your Caddyfile (usually at /etc/caddy/Caddyfile):

example.com {
    root * /var/www/blog
    file_server
}

That’s it! Caddy will automatically provision and renew SSL certificates for your domain. Make sure your DNS is pointing to your server, and you’re good to go.

Autodeployment with GitHub Actions

Here’s a simple GitHub actions to get deployment on push:

---
name: CI

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
    - name: Updating website.
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.PRIVATE_KEY }}
        port: ${{ secrets.SSH_PORT }}
        script: |
          cd blog
          git stash
          git pull --force origin main
          git submodule update
          rm -rf /var/www/blog/*
          hugo --cacheDir ~/hugocache -d /var/www/blog          

Make sure to replace parts as needed! And make sure that the secrets are populated.

That’s it!

Hope this helps, and happy making a Hugo static site!