Installing Hugo on Alpine Linux and serving the static site with Nginx

Nov 14, 2023

In the process of revamping my art site (now offline because I merge my sites into this one), I stumbled upon Hugo, a static site generator similar to Jekyll used for this blog. My art site previously used WordPress. However, in the spirit of trying new things, and because I’m moving this site to my home server, I need it to be low on resource usage.

It only makes sense for me to switch to a static site. Hugo, it turned out, is simpler to learn than Jekyll due to not having to deal with dependencies. At some point in the future I might move this blog to Hugo as well, but I’m currently happy with the blog’s look.

Anyway, Let’s start.

Similar to the previous guide, the goal of this guide is to have a static site generated by Hugo and then we’ll server the site using Nginx webserver. This way, we don’t need Hugo server running all the time. Also, I will assume you have a fresh Alpine Linux 3.18 install. If you’re using Proxmox like me, it’s easy to spin a new Alpine LXC. I’ll use root user for the guide. However, it’s highly recommended to not use root on your production server.

Installing the required software

First, let’s update our Alpine Linux by running the following:

apk update

Followed by:

apk upgrade

These commands will update your repository and upgrade your installed packages to the latest ones.

Next, let’s install the software required to run Hugo. To do that, run this command:

apk add nano nginx hugo git

Explanation of the packages:

Nginx setup

Before going further into Hugo installation, we should ensure that our web server is running correctly and can serve requests. Run this command to enable the Nginx daemon:

rc-update add nginx default

Then start nginx:

rc-service nginx start

By now, you should be able to enter your device IP into your browser, but Nginx will show a 404 page:

 Nginx 404

The next step is to update the Nginx settings. First, backup the default setting by running this command:

mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig

Then, edit the setting by running:

nano /etc/nginx/nginx.conf

And add the text below:

user                            root;
worker_processes                auto; # it will be determined automatically by the number of core

error_log                       /var/log/nginx/error.log warn;
#pid                             /var/run/nginx/; # it permits you to use /etc/init.d/nginx reload|restart|stop|start

events {
    worker_connections          1024;

http {
    include                     /etc/nginx/mime.types;
    default_type                application/octet-stream;
    sendfile                    on;
    access_log                  /var/log/nginx/access.log;
    keepalive_timeout           3000;
    server {
        listen                  80;
        root                    /var/www/public;
        index                   index.html index.htm;
        server_name             localhost;
        client_max_body_size    32m;
        error_page              500 502 503 504  /50x.html;
        location : /50x.html {
              root              /var/lib/nginx/html;

Now restart Nginx:

rc-service nginx restart

Using the rules above, Nginx will run as root and serve files in /var/www/public/. We can test this by creating a simple HTML file:

mkdir /var/www/public && nano /var/www/public/index.html

Add the following code:

<!DOCTYPE html>
<html lang:"en">
    <meta charset:"utf-8" />
    Server is online

Try reaccessing the IP, and you’ll see this:

Nginx working

Hugo setup

Now we get to the spicy part: actually configuring Hugo. To create a new Hugo project, first run this command:

hugo new site hugosite

Then move to the new Hugo directory:

cd hugosite

Initialize an empty Git repository in the new Hugo directory:

git init

You can then install any theme from the Hugo theme repository. For this example, I will use Archie theme:

cd themes
git clone

Then append a line to the site configuration file indicating the current theme:

echo "theme : 'archie'" >> config.toml

Now, we can test the site by running the following command:

hugo server --bind:yourIP

hugo server is the command used to start the server. The --bind flag indicates your device IP if you are accessing from another device. If you’re running and checking this locally, it’s optional.

Now, you can access the site from a web browser by entering yourIP:1313 in your web browser. 1313 is the default Hugo server port.

Hugo server running

Generating Hugo static files and moving them to Nginx root directory

The last step in this guide is to generate the static files from Hugo and then move the files to the Nginx root directory. To accomplish this, first empty the Nginx root directory:

rm -rf /var/www/public/*

Then, generate the static files directly to the Nginx root directory:

hugo --destination:"/var/www/public"

And that’s it! Now, Nginx is serving the generated Hugo files:

Hugo server running

You can take it to the next level by Installing SSL on your self-hosted site and work on the Hugo site more by following the official documentation.