Moving To Hugo
- 4 minutes read - 664 wordsMy WordPress site broke in a way that seemed impossible to recover from. My server updated to PHP 8.0 which caused problems retrieving site info from the SQL database. Updraft (a backup plugin) couldn’t even run to restore the site. Doing a full backup on a new install caused the same issues, and I couldn’t find a way to roll back to PHP 7.4.
Recovering WordPress
Fortunately the Updraft backups in my Google Drive contained a database backup. I was able to manually insert these into a fresh WordPress install without having to add themes and plugins that were expecting an older PHP version. In theory I could do this on my webserver, re-upload the contents of the “Uploads” folder (images etc.), then add themes & plugins to restore the site.
I have been unhappy with the amount of updates WordPress and it’s plugins need and generally felt like there were too many dependencies. That’s why I decided to try Hugo!
Hugo
Hugo is an open source static website generator. It is written in Go and can turn Markdown files into HTML using a theme to generate appropriate CSS. It even has it’s own web server, which is great for quickly previewing changes locally. Jekyll used by GitHub pages is another example of a site generator, which I have used in the past to make RelayStats.
The benefits of using a static site generator are:
- No more reliance on PHP
- No more updating plugins and WordPress separately
- Potentially faster and more responsive site
- Web content easier to backup and port
- Easier content writing and deploying process
- More secure (no PHP and CMS to worry about)
My setup
All the content for my site is now stored in a Git repo and pushed to GitLab (no more Updraft Backups!). The theme for the site is imported as a submodule (I am using Ananke), and modified slightly using some simple CSS. When Hugo generates the site, it is copied to the site root directory to be served using Nginx. While Hugo has it’s own web server, it doesn’t support SSL certificates. That’s it! Cloudflare still handles DNS and caching static content (which is now the whole since, no more page rules for wp-login!). Here is a quick breakdown of what is needed for each:
Hugo | WordPress |
---|---|
- Git | - Updraft |
- Hugo | - WordPress |
- Nginx | - Apache |
- RSync | - MySQL |
- Curl | - PHP |
- Cloudflare (Plugin) | |
- About 10 other plugins |
Deploying
This is what the full process for adding a new page/post to the site looks like
- Create a .md file and write some content
- Run a local Hugo server to check it looks ok on localhoast -
hugo server -D
- Commit and push the changes to GitLab
- GitLab detects changes on the Master branch and runs a CI job to pull the changes on my VPS then run a deploy script
- The deploy script builds the site with Hugo (builds aren’t stored in Git), RSync’s the content to the webserver root, then purgest my Cloudflare Cache
Scripts
Here are the three scripts that make it all work.
GitLab CI
A public key needs to be stored in GitLab CI/CD Varibles (to use protected varibles the branch must also be protected).
- apt-get update -qq
- apt-get install -qq git
# Setup SSH deploy keys
- 'which ssh-agent || ( apt-get install -qq openssh-client )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$sshkey")
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
deploy_staging:
type: deploy
environment:
name: staging
script:
- ssh 'user@server' "cd /hugo/site/path && git checkout master && git pull origin master && git submodule foreach git pull origin master && ./deploy.sh"
only:
- master
Deploy
USER='user_name''
HOST='server_address'
DIR='site_root_dir'
hugo && rsync -avz --delete public/ ${USER}@${HOST}:${DIR}
echo ""
echo "[+] FINISHED..."
echo "Purging Cloudflare Cache"
./purge.sh
exit 0
Purge
-H "X-Auth-Email: 'your_user_name'" \
-H "X-Auth-Key: 'your_api_key" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'