Create blogs with Hugo
Welcome to the first post 😀
Starting today, I will write a small post almost every day about the things that I am personally and professionally involved with.
I would like to begin by reporting on how I set up this blog:
For this, I have installed the tool Hugo.
Hugo is written in Go and allows you to create static websites, such as this blog, without needing to run a server with Node.js or .NET. The finished website consists only of ready-made HTML pages and images, which only need to be sent to the browser.
The content has to be written in Markdown and there are plenty of themes available for every usecase.
As you can see, the loading time is already quite fast and you don’t need to host an expensive server.
Create your webpage
If the tool is installed, create a new project with
hugo new site mywebsite
and then switch to the new directory with
cd mywebsite
It is recommended that git is installed in order to create a new repository using the following commands:
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
which install an example theme using submodule.
In a Unix/Linux terminal, the theme can be added to the configuration file hugo.toml
using the command
echo "theme = 'ananke'" >> hugo.toml
Finally, the development server can be started using the command:
hugo server
and usually accessed through the address http://localhost:1313/ in a browser.
Changes are updated directly in the browser as long as the server is running.
To create a new page, use the command
hugo new content posts/my-first-post.md
which can be accessed at http://localhost:1313/posts/my-first-post/
The new file my-first-post.md
contains a header, as well as content:
+++
title = 'My First Post'
date = 2023-09-05T23:09:00+01:00
draft = true
+++
## Introduction
This is **bold** text, and this is *emphasized* text.
Visit the [The GitFather's Blog](https://blog.kloubert.dev) website!
Once the first pages are completed, they can now be generated for the finished homepage:
hugo
The output files will be placed in the subdirectory public/
and can be opened through the index.html
file.
Automatic Build and Deployment Process with GitHub
If the website is not updated very often, it is usually sufficient to do everything manually from building to saving on the web server.
However, it is more convenient to have a build and release pipeline on Azure DevOps, GitLab, or GitHub.
Personally, I run a Raspberry Pi with Gitea from home.
However, since this requires a lot of effort to set up, I will explain it using GitHub Actions as an example.
This is usually free and completely sufficient for private use.
The good thing about this is that the setup is very simple, as you only need to upload a YAML file like publish.yaml
to the subdirectory .github/workflows/
in your GitHub repository.
GitHub recognizes this automatically and immediately starts the tasks as described there.
The publish.yaml
could look like this, for example:
name: Build and publish
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build website
run: bin/hugo -D --config ./hugo.toml
- name: Cleanup target directory
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
rm -rfv ~/transfer/blog.example.com
mkdir -v -p ~/transfer/blog.example.com
sudo rm -rfv /var/www/blog.example.com/*
script_stop: true
- name: Upload directory
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
source: "public/*"
target: "~/transfer/blog.example.com"
- name: Move to target
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
sudo mv -v ~/transfer/blog.example.com/public/* /var/www/blog.example.com
sudo chown -R -v www-data:www-data /var/www/blog.example.com/*
script_stop: true
With
name: Build and publish
the display name is set for display the action on GitHub.
on:
push:
branches:
- main
This specifies that the GitHub Action should be executed when changes are pushed to the main
branch.
Next, the steps to be executed are defined:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Here, the action is executed in a current Ubuntu container and the code is checked out at the beginning using actions/checkout@v4.
The step
- name: Build website
run: bin/hugo -D --config ./hugo.toml
builds the website with an x64 binary, which can be downloaded at https://github.com/gohugoio/hugo/releases and must be placed in the subdirectory bin/
of the GitHub repository.
- name: Cleanup target directory
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
rm -rfv ~/transfer/blog.example.com
mkdir -v -p ~/transfer/blog.example.com
sudo rm -rfv /var/www/blog.example.com/*
script_stop: true
uses the appleboy/ssh-action to delete the directory on the target server.
The host, port, username, and SSH key of the target server are stored as secrets.
With appleboy/scp-action, the created files from the public/
folder will be uploaded to the target server:
- name: Upload directory
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
source: "public/*"
target: "~/transfer/blog.example.com"
The last step
- name: Move to target
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
sudo mv -v ~/transfer/blog.example.com/public/* /var/www/blog.example.com
sudo chown -R -v www-data:www-data /var/www/blog.example.com/*
script_stop: true
moves the uploaded files to /var/www/blog.example.com
folder and assigns them to user and group www-data
.
The files can then be easily hosted using lighttpd, NGINX, or Apache.
Once set up, you save yourself a lot of work and stress and you learn something in the process 👍
Have fun!