Hugo August 18, 2023

Hugo Blog Deploy with Nginx

A practice of Hugo & Nginx in 2023

Notation

  • CAPITAL WORDS should be replaced by yourself
  • /* */ denotes comment

Introduction

It has been a long-time willing for me to create a personal blog. Ever since I learned the basic usage of Markdown, I have been looking for a way to build a blog upon it.

A blog based on Markdown is clearly pointing to the static site generator. There are several choices: Hexo, Hugo, Jekyll, etc.. I chose Hugo over the others simply because it’s written in Go, therefore you don’t need to install dozens of javascript/npm/ruby packages to make it barely working. Hugo is quite a neat but robust framework to start with.

However, many issues are yet to be addressed only until I stepped onto them, because many tutorials are outdated and misleading. In this post, I’m going to share some experience during the process of constructing enclave.blog.

Server Side

Firstly, you need a domain name that points to your server IP (My recommendation is choosing Namesilo as your domain name server), make sure you ping to the domain and get the right IP and have full access to it (by SSH, mostly). I use a Debian 10 server, which is a little old when it comes to the version of some programs.

Prerequisite installations:

# apt-get update && upgrade
# apt-get install software-properties-common
# add-apt-repository universe
# add-apt-repository ppa:certbot/certbot
# apt install nginx rsync certbot python3-certbot-nginx

Notice: I installed rsync because I use a Linux desktop, and it’s the simplest way to convey code or data between Linux machines. You can also choose scp or ftp for alternative.

# mkdir -p /etc/nginx/sites-available
# mkdir -p /etc/nginx/sites-enabled

# mkdir -p /var/www/SITE_NAME/public

While many posts or tutorials I searched on google suggested that sites-available and sites-enabled already exist under /etc/nginx, clearly, I didn’t found them in 2023 on debian 10. According to some issue discussions, these directories have been obsoleted in current version of nginx, so you have to create them firstly. Plus, if these two directories exist in your server, do remember to rm any default file under them.

Then, create a file with your desired web name under /etc/nginx/sites-available/, e.g. vim /etc/nginx/sites-available/SITE_NAME:

server {
       listen 80;
       listen [::]:80;

       server_name SITE_NAME.com www.SITE_NAME.com;

       root /var/www/SITE_NAME/public;
       index index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

The root directory can be chosen yourself, but do avoid home directories.

Remember to create a symbolic link:

# ln -s /etc/nginx/sites-available/SITE_NAME /etc/nginx/site-enabled/SITE_NAME

Very Important: Add one extra line to the http section of /etc/nginx/nginx.conf.

...
http {
	...

	include /etc/nginx/sites-enabled/*;
}
...
# systemctl enable --now nginx

Visit your site by its domain name (begin with http://, because you haven’t set up ssl yet) in your web browser, you should see the web page just like this:

|inline

Notice: I didn’t install Hugo on server because its version on Debian 10 is so outdated (v0.54.0 comparing to v0.116.1 on Arch Linux) that your local Hugo publication cannot be reproduced on server. You can, however, fix it by installing Hugo from platforms such as snap and flatpack with the same version of your desktop. In my opinion, since Hugo itself is only a static website generator, you could generate all the website staffs at local and only transfer them to server, to save the storage.

So far so good, the next thing to do on server is setting https via ssl:

# certbot --nginx

Just follow the guide of script, it will automatically modify your nginx.conf and add lines required by ssl

Desktop Side (UNIX/Linux/MacOS)

For installations:

$ sudo pacman -S hugo rsync
/* package manager referring to your OS */

$ cd HUGO_ROOT_DIR
$ hugo new site SITE_NAME

The directory of Hugo new site should be like:

.
├── archetypes
│   └── default.md
├── assets
├── content
├── data
├── hugo.toml
├── layouts
├── static
└── themes

After initiating, the next thing to do is to choose a theme. As mentioned earlier, you can find one from the official theme site Hugo Themes.

After you following the guide of the theme page, where the author provides ways of installation (git clone or git submodule or download compressed file and unpack it). You can begin to make the first post.

$ echo "theme = 'THEME_NAME'" >> hugo.toml

$ hugo new content posts/test.md

$ vim content/posts/test.md

The first three lines of test.md look like:

title: "test"
date: 2023-08-18T09:00:00-08:00
draft: true

Notice: You can change the default of front matter in archetypes/default.md. Refer to the guideline of your chosen theme.

Write something using the grammar of Markdown, and remember to delete the line of draft: true in front matter, otherwise this post will not show in your web.

$ cd HUGO_ROOT_DIR
/* otherwise hugo will report error */

$ hugo server

If you follow through, prompts will pop out and lead you to http://localhost:1313/, where you can test the generated blog in local machine.

Include images in Markdown posts

It’s worthy noting that the root directory when linking images is referred to HUGO_ROOT_DIR/static/:

  • store all images in static/
  • link by ![IMG_TEXT](/IMAGE_NAME.PNG)

Furthermore, for any directories under /static: /static/DIR, refer to them as ![IMG_TEXT](/DIR/IMAGE_NAME.PNG)

Synchronize and Publicize

To store your SSH ID in the server side, and avoid inputting password every time: use ssh-copy-id tool.

$ ssh-copy-id -i ~/.ssh/MYKEY root@SERVER_IP
/* MYKEY looks like id_xxx.pub */

If you finished your writing of posts and want to publicize to the internet:

$ cd HUGO_ROOT_DIR
$ hugo

$ rsync -r ./public/ USER@SERVER_IP:/var/www/SITE_NAME/public
$ ssh root@SERVER_IP 'systemctl restart nginx'

It’s almost everything, now open the web browser and type in your domain name(with https:// this time). You shall see an identical blog as presented by running $ hugo server in your desktop.

Copyright: Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

Author: Benny

Posted on: August 18, 2023