Deploying a website built with Hugo
I have previously talked about creating a personal website, in this post I will talk about hosting it. More specifically, I'm going to explain how to host a website built with Hugo.
Hosting without a server
If you don't have a server or don't want to be in charge of one, you can let GitLab host your
website. You can either do it with your own domain or use the one GitLab will assign you based on
your username. If you want to do it this way, take a look at their example, you only need to add that
.gitlab-ci.yml
file to your repository and GitLab will do the rest.
There are other services that will host a static site for free like Netlify (which supports Hugo) or services that host a site given the HTML files such as Neocities—in this case, you would need to run Hugo locally and upload the output files.
Hosting with a server
If you have a server or would like to run one, you can host your website there. Let's see how to
do it using Apache. First of all, we will install Apache and Hugo on our server and clone our
site's repository somewhere. In my case, my Hugo directory is found in the /srv
directory and the actual files that should be served are in the public
folder inside
the directory1. Therefore, the directory I want to serve
is /srv/<hugo_directory>/public
(created by Hugo).
Before we begin, let's edit Apache's configuration to deny access to the default folders. I am not
sure if this is actually necessary as you will be setting up site root directories, but I like to
restrict any access and then grant it on a per-site basis. Go to the Apache configuration file
found at /etc/apache2/apache2.conf
and comment the lines with the following content
(put a #
at the start of the line):
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory /srv/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
That will restrict access to the specified directories (which will not be public from now on). In
order to grant access to the desired folder, we'll create a file under
/etc/apache2/sites-available
with the site's configuration. I like to name the files
after the (sub)domain, so I would put my apache configuration in the file
/etc/apache2/sites-available/<domain_name>.conf
, with the following
configuration:
<VirtualHost *:80>
ServerName <domain_name>
DocumentRoot /srv/<hugo_directory>/public
ErrorLog ${APACHE_LOG_DIR}/error-<domain_name>.log
CustomLog ${APACHE_LOG_DIR}/access-<domain_name>.log combined
<Directory "/srv/<hugo_directory>/public">
Options FollowSymLinks
AllowOverride None
Require all granted
ErrorDocument 403 /404.html
ErrorDocument 404 /404.html
</Directory>
</VirtualHost>
What is happening here? We are creating a virtual host for incoming connections on port 80
(default HTTP port) that will respond to requests to the <domain_name>
domain
(specified on the ServerName
). The root folder for the domain will be
/srv/<hugo_directory>/public
(so if you access
http://<domain_name>/blog/index.html
, it will serve with the file found at
/srv/<hugo_directory>/public/blog/index.html
). After that, we set up the error
and access log files (the domain part of the name is not necessary, especially if you are only
hosting one service).
The second part of the file looks similar to the commented lines above, and they actually do the same job, we just have them in this file which makes it easier to keep track of which directories is each site depending on and their permissions. In this case, we allow Apache to follow symbolic links and we give access to our files to any user on the web (we won't ask for a password). On top of that, I specified a custom 404 file (which will also be served when the visitor is trying to access a restricted file or directory, which gives error 403).
Configuration ready! We'll need to activate it using the following command as the root user:
a2ensite <domain_name>.conf
And just make sure your DNS is pointing to the server. Everything should work now! However, we are serving our page through HTTP, we definitely want HTTPS. It might sound unnecessary since we don't have any forms on our website (no data to be encrypted), but HTTPS also guarantees site authenticity (protects you against man-in-the-middle attacks) and normalizes the use of encryption on the web.
In order to set up HTTPS, we need a certificate. I use one issued by Let's Encrypt, which are free and very easy to use (and they are renewed automatically). To do so, I use Certbot, developed by the EFF. To use it, go to the Certbot's page, install it on your server and follow the instructions on the website. Make sure you enable redirection to HTTPS!
It takes about 2 minutes to set up and now people will connect to your site using HTTPS. You can
see that a new file has been created at
/etc/apache2/sites-available/<domain_name>-le-ssl.conf
by Certbot to configure
the HTTPS site, plus a couple of lines will be added to the configuration file on port 80 to
redirect to the encrypted site.
Your site is ready!
-
It is also a common practice to put it under
/var/www
. ↩