In this tutorial, we'll deploy Hugo static site on AlmaLinux with Nginx.
We’ve all experienced the joy of lightning-fast, rock-solid websites—and static site generators like Hugo make it remarkably easy to deliver exactly that. In this tutorial, we’ll walk through deploying a Hugo site on AlmaLinux 9 and serving it with Nginx. Along the way we’ll explain why each step matters, share best practices, and show how to turn our Markdown-based content into a production-ready website.
Deploying a Hugo site on an AlmaLinux 9 server with Nginx is a powerful way to serve blazing-fast, secure static content. In this guide, we’ll walk through every step—from preparing the OS to tuning Nginx—so that our Hugo site runs smoothly in production. Let’s dive in.
Why Hugo on AlmaLinux 9?
Hugo is one of the fastest static site generators available, written in Go and capable of generating thousands of pages in milliseconds. AlmaLinux 9, a Red Hat Enterprise Linux (RHEL)–compatible distribution, provides rock-solid stability and long-term support, making it ideal for hosting production workloads. Coupling Hugo with Nginx gives us an efficient, low-overhead web server that excels at serving static assets.
Prerequisites
Before we begin, let’s ensure we have the following in place:
- A Ubuntu 24.04 dedicated server or KVM VPS.
- A basic programming knowledge.
- A domain name pointing at server IP.
Deploy Hugo Static Site on Ubuntu with Nginx
Step 1: Prepare and Update the Server
Before installing anything, let’s make sure our system is up to date and secured.
sudo dnf clean all
sudo dnf update -y
After update, reboot if the kernel was upgraded:
sudo reboot
Step 2: Install Dependencies
We need a few tools: Git (to clone themes or your site repo), wget (for downloads), and firewalld to manage ports.
sudo dnf install -y git wget firewalld
sudo systemctl enable --now firewalld
Step 3: Install Hugo
We have two main options: install via the EPEL repository (may lag behind latest Hugo), or download the official binary.
Option A: EPEL (quick, possibly older)
sudo dnf install -y epel-release
sudo dnf install -y hugo
Option B: Official Binary (ensure the latest)
Visit https://github.com/gohugoio/hugo/releases and identify the latest extended Linux tar.gz (extended supports Sass/SCSS).
On the server:
HUGO_VERSION="0.115.0" # replace with latest release
wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
tar -xzf hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
sudo mv hugo /usr/local/bin/
rm hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
Verify:
hugo version
You should see output like
hugo v0.147.6-0a5fd8ebb8e2ca798515e8c564c14e32db3b4127+extended linux/amd64 BuildDate=2025-05-27T11:17:16Z VendorInfo=gohugoio
Step 4: Create or Deploy Our Hugo Site
If we’re starting fresh:
hugo new site ~/our-hugo-site
cd ~/our-hugo-site
This scaffolds a minimal Hugo directory structure (hugo.toml, content/, layouts/, etc.).
If we’re deploying an existing site:
cd /var/www/our-hugo-site
git clone https://github.com/your-org/your-hugo-repo.git .
Step 5: Add a Theme and Configure
Most Hugo sites use a theme. For example, the popular “Ananke” theme:
cd themes
git clone https://github.com/theNewDynamic/gohugo-theme-ananke.git ananke
cd ..
Edit hugo.toml:
nano hugo.toml
Adjust it like following (Replace https://example.com/ with your domain name):
baseURL = "https://example.com/"
languageCode = "en-us"
title = "Our Hugo Site"
theme = "ananke"
Adjust parameters (menus, taxonomies, params) per the theme’s README. This is where we make our site truly ours.
Step 6: Build the Static Files
We can generate the full site into Hugo’s default public/ folder:
cd ~/our-hugo-site
hugo --minify
- --minify strips unnecessary whitespace from HTML, CSS, and JS for faster delivery.
The built files live in ~/our-hugo-site/public/
.
Step 7: Install and Configure Nginx
Install Nginx:
sudo dnf install -y nginx
sudo systemctl enable --now nginx
Open HTTP/HTTPS ports:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Nginx Server Block
Create /etc/nginx/conf.d/our-hugo-site.conf:
nano /etc/nginx/conf.d/our-hugo-site.conf
Add following content:
server {
listen 80;
server_name example.com www.example.com;
root /usr/share/nginx/our-hugo-site/public;
index index.html;
# Serve static assets with far-future expires headers
location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public";
}
location / {
try_files $uri $uri/ =404;
}
}
Test and reload:
sudo nginx -t
sudo systemctl reload nginx
Step 8: Deploy Files to Nginx Root
Move or synchronize built files:
cd ..
sudo mv our-hugo-site/ /usr/share/nginx/
sudo chown -R nginx:nginx /usr/share/nginx/our-hugo-site
Step 9: Configure SELinux
If you have enabled SELinux, follow this step:
Apply the correct file context to your Hugo output directory:
sudo semanage fcontext -a -t httpd_sys_content_t "/usr/share/nginx/our-hugo-site/public(/.*)?"
sudo restorecon -Rv /usr/share/nginx/our-hugo-site/public
Step 10: Enable HTTPS with Let’s Encrypt
Security is paramount. We can secure our site with a free SSL certificate:
Install Certbot:
sudo dnf install -y certbot python3-certbot-nginx
Obtain and configure certificate:
sudo certbot --nginx -d example.com -d www.example.com
Certbot will modify our Nginx config to redirect HTTP to HTTPS and reload automatically. Certificates renew every 90 days; Certbot sets up a cron job.
Step 11: Automate Future Builds
In a production workflow, we’ll update content in our Hugo project, then rebuild and sync:
cd ~/our-hugo-site
git pull origin main
hugo --minify
rsync -av --delete public/ /var/www/our-hugo-site/public/
sudo systemctl reload nginx
We can script this or integrate into a CI/CD pipeline (e.g., GitHub Actions) so that every push to the main branch automatically publishes the site.
Wrapping Up
In this tutorial, we've deployed Hugo static site on AlmaLinux with Nginx. By combining Hugo, AlmaLinux 9, and Nginx, we’ve assembled a high-performance, secure static site setup. Our content is easy to manage in Markdown, builds are lightning fast, and Nginx efficiently serves cached assets.
Whether we’re running a personal blog or a documentation hub, this stack gives us both speed and reliability. Let’s raise a toast to modern static hosting—lightweight, robust, and totally under our control!