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