+++
title = "My current website setup"
aliases = '/posts/2023-01-24-my-current-website-setup'
summary = """This is how I install hugo nowadays. Although that routine might
change anytime."""
date = "2023-01-24T22:36:25+0100"
lastmod = '2024-09-28T23:48:06+0000'
categories = ["computerstuff"]
tags = ["linux", "server", "gohugo", "selfhost", "website-news"]

+++

Since I started writing down notes about my website-setup some of the
infrastructure changed. In the meantime I moved away from Github and host
my personal Gitea instance on my server. Some of the notes have been
re-written, but I could have forgotten something -- so take the following
information with a grain of salt maybe. Prepare to adopt to your needs.

{{% alert %}}
This article is already out of date. But it has been a nice experience.
{{% /alert %}}

## Install hugo from source

This is done on your computer.

### Requirements

- Install Git

  Depending on your <abbr title="Operating System">OS</abbr>, this might look
  like one of those:

  ```console
  $ sudo apt install git
  ```

  ```console
  $ sudo pacman -S git
  ```

- Install Go version 1.18 or later

  See above for the syntax, this package may be called `golang` on some
  distributions (I think Ubuntu/Debian for example).

- Update your PATH environment variable as described in the Go documentation

  Now, that looks like this:

  ```zsh
  if [[ -d $HOME/go ]]; then
    export GOPATH="$HOME/go"
    path=(
      $GOPATH/bin
      $path
    )
  fi
  ```

  _That is an example taken from my `.zprofile` file._

### Install hugo

We are still on our computer.

```console
$ go install -tags extended github.com/gohugoio/hugo@latest
```

That installs the latest version of hugo into `$HOME/go/bin`. If your terminal
does not recognize the new binaries: `hash -r` or `rehash` might help...

Source: <https://gohugo.io/installation/linux/#build-from-source>

## Adding themes as hugo modules

Just to be more clear on this: I'm using the congo theme for hugo right here.

{{< alert >}}
Ensure you have Go and Hugo installed, and that you have created a new
hugo project before proceeding.
{{< /alert >}}

From your project directory, initialise hugo modules:

```console
$ hugo mod init github.com/<username>/<repo-name>
```

Create `config/_default/module.toml` and add the following:

```toml
[[imports]]
path = "github.com/jpanther/congo/v2"
```

Start your server using `hugo server` and the theme will be downloaded
automatically.

Remove the file `config.toml` from your website root directory (generated by
`hugo site new...`). Copy the config files from the theme into `config/_default/`.

{{< alert >}}
Note: Do not overwrite the `module.toml` file you created above!
{{< /alert >}}

You will find these theme config files in the Hugo cache directory, or download
[a copy from GitHub](https://github.com/jpanther/congo/tree/dev/config/_default).

Follow the [Getting Started instructions](https://jpanther.github.io/congo/docs/getting-started/)
to configure your website.

## Using Atom for feeds (replacing RSS)

Define an appropriate media type and corresponding output format in `config.toml`:

```toml
[mediaTypes]
[mediaTypes."application/atom"]
suffixes = ["xml"]

[outputFormats.Atom]
mediaType = "application/atom"
baseName = "index"
isPlainText = false
```

Tell hugo to produce the home page in Atom and HTML (and JSON) formats,
also append this in `config.toml`:

```toml
[outputs]
home = [ "HTML", "Atom", "JSON" ]
```

Put an `index.atom.xml` template file in your layouts directory. You can use the
attached one as a starting point, don't forget to edit the author element
appropriately or make it use the values from your config.

```xml
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
  <link rel="self" href="{{ .Permalink }}"/>
  <updated>{{ .Date.Format "2006-01-02T15:04:05-0700" | safeHTML }}</updated>
  <author>
    <name>YOUR NAME HERE</name>
    <email>YOUR EMAIL ADDRESS</email>
    <uri>DEFINITIVE URI OF YOUR WEB SITE</uri>
  </author>
  <id>{{ .Permalink }}</id>
  {{ range first 15 .Data.Pages }}
  <entry>
    <title>{{ .Title }}</title>
    <link rel="alternate" href="{{ .Permalink }}"/>
    <id>{{ .Permalink }}</id>
    <published>{{ .Date.Format "2006-01-02T15:04:05-0700" | safeHTML }}</published>
    <updated>{{ .Lastmod.Format "2006-01-02T15:04:05-0700" | safeHTML }}</updated>
    <summary>{{ .Summary | html }}</summary>
  </entry>
  {{ end }}
</feed>
```

Source: <https://gist.github.com/lpar/7ded35d8f52fef7490a5be92e6cd6937>

## Auto-clear Cloudflare cache on git push

If we use Cloudflare, we want the cache to be cleared. We are still on
our computer.

### Requirements

- A **Cloudflare website** (not pages)
- An API token on Cloudflare to let git clear your website's cache (see below)

### Cloudflare setup

Create a file `.cloudflarerc` in your `$HOME` directory that contains those two
variables:

```bash
apikey=*********************************-******
id=********************************
```

You find them in your [Cloudflare dashboard](https://dash.cloudflare.com/).
Click on <kbd>Websites</kbd> and continue with clicking your domain name.
Scroll down a bit and find your `id` on the right sidebar. It is called
_Zonen-ID_ (within API). Below that is a link called _Ihr API-Token erhalten_.
Click it and create a user-defined API token. I'll show you a screenshot of
mine, edit yours to fit this example.

![Screenshot of my token settings and rights](01_api-token-settings.png)

Click <kbd>Create token</kbd> and copy the resulting token into your
`.cloudflarerc` file.

### git repository setup

Now we need one last file in our git repository. Create `.git/hooks/pre-push` and
fill it with this:

```bash
#!/bin/bash

if ! [ -f ~/.cloudflarerc ] ; then
  echo "No ~/.cloudflarerc file found. Cloudflare clear cache SKIPPED."
  exit 0
fi

. ~/.cloudflarerc

echo -n "Clearing cloudflare cache..."

ret="$(curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$id/purge_cache" \
     -H "Authorization: Bearer $apikey" \
     -H "Content-Type: application/json" \
     --data '{"purge_everything":true}')"

if [ -n "$(echo $ret | grep success)" ] ; then
  echo " Success!"
else
  echo " *** FAILED ***"
  echo "Could not clear cloudflare's cache. Update will not proceed."
  # exit with 1, so the update does not proceed, so we will know
  exit 1
fi
```

I found the script on
<https://www.supertechcrew.com/clear-cloudflare-cache-when-pushing-from-git-github-pages/>
-- which is also a good read if my explanation won't work for you.

Don't forget to make this script executable:

```console
$ chmod +x .git/hooks/pre-push
```

## Publish the website

Since the end of December 2022 I use my own git hosting service on my
own server. I used Github before that.

If you save your website repository on Github: create a Cloudflare page
and you are probably good to go. Don't forget to enable that page in
the website settings at Cloudflare.

Okay, since I stopped using Github I have to publish my git repository
somewhere to the public root of my webserver. That is done via a
post-receive hook on the git servers repository.

It's actually the file `website.git/hook/post-receive.d/publish`:

```bash
#!/usr/bin/env bash

# change these to your needs...
GIT_REPO=/var/.../website.git
WORKING_DIR=${HOME}/website-working
PUBLIC_WWW=/var/www/html
BACKUP_WWW=/var/www/backup
MY_DOMAIN=website.com

set -e

rm -rf ${WORKING_DIR}
rsync -aqz ${PUBLIC_WWW}/ ${BACKUP_WWW}
trap "echo 'A problem occured. Reverting to backup.'; rsync -aqz --del ${BACKUP_WWW}/ ${PUBLIC_WWW}; rm -rf ${WORKING_DIR}" EXIT

git clone ${GIT_REPO} ${WORKING_DIR}
rm -rf ${PUBLIC_WWW}/*
/home/git/go/bin/hugo --gc --minify --cleanDestinationDir -s ${WORKING_DIR} -d ${PUBLIC_WWW}
rm -rf ${WORKING_DIR}
trap - exit
```

If you use Gitea, those repositories are per default in
`/var/lib/gitea/data/gitea-repositories/`...

That is it, basically.