2020-02-12-deploying-hugo-site.md (5925B) - raw


      1 <!-- title: Deploying a website built with Hugo -->
      2 <!-- slug: deploying-hugo-site -->
      3 <!-- categories: Personal domain, Self-hosting -->
      4 <!-- date: 2020-02-12T00:00:00Z -->
      5 
      6 I have [previously talked][post] about creating a personal website, in this post
      7 I will talk about hosting it. More specifically, I'm going to explain how to
      8 host a website built with Hugo.
      9 
     10 ## Hosting without a server
     11 
     12 If you don't have a server or don't want to be in charge of one, you can let
     13 GitLab host your website. You can either do it with your own domain or use the
     14 one GitLab will assign you based on your username. If you want to do it this
     15 way, take a look at [their example][ex], you only need to add that
     16 `.gitlab-ci.yml` file to your repository and GitLab will do the rest.
     17 
     18 There are other services that will host a static site for free like Netlify
     19 (which supports Hugo) or services that host a site given the HTML files such as
     20 Neocities—in this case, you would need to run Hugo locally and upload the output
     21 files.
     22 
     23 ## Hosting with a server
     24 
     25 If you have a server or would like to run one, you can host your website there.
     26 Let's see how to do it using Apache. First of all, we will install Apache and
     27 Hugo on our server and clone our site's repository somewhere. In my case, my
     28 Hugo directory is found in the `/srv` directory and the actual files that should
     29 be served are in the `public` folder inside the directory[^var]. Therefore, the
     30 directory I want to serve is `/srv/<hugo_directory>/public` (created by Hugo).
     31 
     32 [^var]: It is also a common practice to put it under `/var/www`.
     33 
     34 Before we begin, let's edit Apache's configuration to deny access to the default
     35 folders. I am not sure if this is actually necessary as you will be setting up
     36 site root directories, but I like to restrict any access and then grant it on a
     37 per-site basis. Go to the Apache configuration file found at
     38 `/etc/apache2/apache2.conf` and comment the lines with the following content
     39 (put a `#` at the start of the line):
     40 
     41 ```apache
     42 <Directory /var/www/>
     43   Options Indexes FollowSymLinks
     44   AllowOverride None
     45   Require all granted
     46 </Directory>
     47 
     48 <Directory /srv/>
     49   Options Indexes FollowSymLinks
     50   AllowOverride All
     51   Require all granted
     52 </Directory>
     53 ```
     54 
     55 That will restrict access to the specified directories (which will not be public
     56 from now on). In order to grant access to the desired folder, we'll create a
     57 file under `/etc/apache2/sites-available` with the site's configuration. I like
     58 to name the files after the (sub)domain, so I would put my apache configuration
     59 in the file `/etc/apache2/sites-available/<domain_name>.conf`, with the
     60 following configuration:
     61 
     62 ```apache
     63 <VirtualHost *:80>
     64     ServerName <domain_name>
     65     DocumentRoot /srv/<hugo_directory>/public
     66     ErrorLog ${APACHE_LOG_DIR}/error-<domain_name>.log
     67     CustomLog ${APACHE_LOG_DIR}/access-<domain_name>.log combined
     68 
     69     <Directory "/srv/<hugo_directory>/public">
     70         Options FollowSymLinks
     71         AllowOverride None
     72         Require all granted
     73 
     74         ErrorDocument 403 /404.html
     75         ErrorDocument 404 /404.html
     76     </Directory>
     77 </VirtualHost>
     78 ```
     79 
     80 What is happening here? We are creating a virtual host for incoming connections
     81 on port 80 (default HTTP port) that will respond to requests to the
     82 `<domain_name>` domain (specified on the `ServerName`). The root folder for the
     83 domain will be `/srv/<hugo_directory>/public` (so if you access
     84 `http://<domain_name>/blog/index.html`, it will serve with the file found at
     85 `/srv/<hugo_directory>/public/blog/index.html`). After that, we set up the error
     86 and access log files (the domain part of the name is not necessary, especially
     87 if you are only hosting one service).
     88 
     89 The second part of the file looks similar to the commented lines above, and they
     90 actually do the same job, we just have them in this file which makes it easier
     91 to keep track of which directories is each site depending on and their
     92 permissions. In this case, we allow Apache to follow symbolic links and we give
     93 access to our files to any user on the web (we won't ask for a password). On top
     94 of that, I specified a custom 404 file (which will also be served when the
     95 visitor is trying to access a restricted file or directory, which gives error
     96 403).
     97 
     98 Configuration ready! We'll need to activate it using the following command as
     99 the root user:
    100 
    101 ```bash
    102 a2ensite <domain_name>.conf
    103 ```
    104 
    105 And just make sure your DNS is pointing to the server. Everything should work
    106 now! However, we are serving our page through HTTP, we [definitely][dmsnh] want
    107 HTTPS. It might sound unnecessary since we don't have any forms on our website
    108 (no data to be encrypted), but HTTPS also guarantees site authenticity (protects
    109 you against man-in-the-middle attacks) and normalizes the use of encryption on
    110 the web.
    111 
    112 In order to set up HTTPS, we need a certificate. I use one issued by [Let's
    113 Encrypt][le], which are free and very easy to use (and they are renewed
    114 automatically). To do so, I use [Certbot][cb], developed by the [EFF][eff]. To
    115 use it, go to the Certbot's page, install it on your server and follow the
    116 instructions on the website. Make sure you enable redirection to HTTPS!
    117 
    118 It takes about 2 minutes to set up and now people will connect to your site
    119 using HTTPS. You can see that a new file has been created at
    120 `/etc/apache2/sites-available/<domain_name>-le-ssl.conf` by Certbot to configure
    121 the HTTPS site, plus a couple of lines will be added to the configuration file
    122 on port 80 to redirect to the encrypted site.
    123 
    124 Your site is ready!
    125 
    126 
    127 [post]: </blog/2019/12/your-corner-of-the-internet/> "Your corner of the Internet — Oscar Benedito"
    128 [ex]: <https://gitlab.com/pages/hugo> "GitLab Pages Examples: Hugo — GitLab"
    129 [dmsnh]: <https://doesmysiteneedhttps.com/> "Does my site need HTTPS?"
    130 [le]: <https://letsencrypt.org> "Let's Encrypt"
    131 [cb]: <https://certbot.eff.org/> "Certbot"
    132 [eff]: <https://www.eff.org/> "Electronic Frontier Foundation"