Last updated on 7th March 2026

Deploy Hugo Static Sites with DeployHQ

Prerequisites:

  • A server with SSH or SFTP access (VPS, dedicated, or shared hosting)
  • A Hugo project in a Git repository
  • A DeployHQ account

What is Hugo?

Hugo is a static site generator written in Go. It's the fastest SSG available — building thousands of pages in under a second — and ships as a single binary with zero dependencies. No Node.js runtime, no Ruby, no Python. Just download the binary and run it.

Hugo powers documentation sites, blogs, marketing pages, and portfolios. Its templating system is based on Go's html/template package, and it supports content organisation through taxonomies, sections, and archetypes.

Hugo has over 80,000 GitHub stars and a mature ecosystem of themes and modules.

Step 1: Install Hugo

macOS (Homebrew): bash brew install hugo

Ubuntu/Debian: bash sudo apt install hugo

Binary download (any platform): ```bash

Download the extended version (includes SCSS support)

curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz sudo mv hugo /usr/local/bin/ ```

Always use the extended version. The standard version lacks SCSS/SASS compilation, which most themes require.

Verify installation: ```bash hugo version

hugo v0.145.0-extended ...


## Step 2: Create a Hugo Site

```bash
hugo new site my-site
cd my-site

Add a theme (most Hugo sites use one): bash git init git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke

Configure the theme in hugo.toml: toml baseURL = 'https://example.com/' languageCode = 'en-gb' title = 'My Site' theme = 'ananke'

Create your first post: bash hugo new content posts/my-first-post.md

Start the development server: bash hugo server -D

The site is available at http://localhost:1313 with live reload.

Step 3: Project Structure

my-site/
├── archetypes/          # Content templates for hugo new
│   └── default.md
├── assets/              # Files processed by Hugo Pipes (SCSS, JS)
├── content/             # Markdown content files
│   └── posts/
│       └── my-first-post.md
├── data/                # Data files (JSON, YAML, TOML)
├── i18n/                # Translation strings
├── layouts/             # Template files
│   ├── _default/
│   │   ├── baseof.html
│   │   ├── list.html
│   │   └── single.html
│   └── partials/
├── static/              # Static files copied as-is (favicon, robots.txt)
├── themes/              # Theme directory (usually Git submodules)
│   └── ananke/
├── hugo.toml            # Site configuration
└── go.mod               # Hugo module dependencies (optional)

Key Directories

  • content/ — Markdown files with YAML/TOML front matter. Directory structure maps to URL structure.
  • layouts/ — Go templates. Override theme templates by placing files with the same path here.
  • assets/ — Files that Hugo processes (SCSS compilation, image resizing, JS bundling).
  • static/ — Files copied verbatim to public/. Use for favicons, robots.txt, pre-built assets.
  • themes/ — Installed themes. Typically Git submodules.

Step 4: Configuration

Hugo supports hugo.toml, hugo.yaml, or hugo.json. TOML is the convention.

baseURL = "https://example.com/"
languageCode = "en-gb"
title = "My Hugo Site"
theme = "ananke"

[params]
  description = "A Hugo site deployed with DeployHQ"
  author = "Your Name"

[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true  # Allow raw HTML in markdown

[outputs]
  home = ["HTML", "RSS", "JSON"]  # Enable JSON for search

[minify]
  disableCSS = false
  disableHTML = false
  disableJS = false
  disableJSON = false
  disableSVG = false
  disableXML = false

Environment-Specific Configuration

Hugo supports configuration directories for per-environment settings:

config/
├── _default/
│   └── hugo.toml        # Base configuration
├── production/
│   └── hugo.toml        # Production overrides
└── staging/
    └── hugo.toml        # Staging overrides

Build with a specific environment: bash hugo --minify --environment production

Step 5: Core Features

Content Management

Hugo content uses front matter for metadata:

---
title: "My Post Title"
date: 2026-03-07
draft: false
tags: ["deployment", "hugo"]
categories: ["tutorials"]
description: "A brief description for SEO"
---

Post content in Markdown here.

Taxonomies

Hugo supports taxonomies (tags, categories, or custom):

[taxonomies]
  tag = "tags"
  category = "categories"
  series = "series"

Shortcodes

Reusable content snippets:

{{< youtube dQw4w9WgXcQ >}}
{{< figure src="/images/photo.jpg" caption="A photo" >}}

Hugo Pipes (Asset Processing)

Process SCSS, fingerprint assets, and minify in templates:

{{ $style := resources.Get "scss/main.scss" | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}" integrity="{{ $style.Data.Integrity }}">

Image Processing

Hugo can resize and convert images at build time:

{{ $image := resources.Get "images/hero.jpg" }}
{{ $small := $image.Resize "600x webp" }}
<img src="{{ $small.RelPermalink }}" alt="Hero" width="{{ $small.Width }}" height="{{ $small.Height }}">

Multilingual Support

defaultContentLanguage = "en"

[languages]
  [languages.en]
    title = "My Site"
    weight = 1
  [languages.fr]
    title = "Mon Site"
    weight = 2

Content is organised per-language: content/en/posts/ and content/fr/posts/.

Step 6: Build for Production

hugo --minify

Output goes to public/:

public/
├── index.html
├── index.xml           # RSS feed
├── sitemap.xml
├── posts/
│   ├── index.html      # List page
│   └── my-first-post/
│       └── index.html  # Single page
├── tags/
├── categories/
├── css/
├── js/
└── images/

Hugo generates clean URLs by default: /posts/my-first-post/ serves posts/my-first-post/index.html.

Build statistics: bash hugo --minify --printPathWarnings --printUnusedTemplates

Step 7: Deploy with DeployHQ

Create a DeployHQ Project

  1. Sign up at deployhq.com
  2. Create a new project and connect your Git repository
  3. DeployHQ automatically installs a webhook for push-triggered deployments

Configure the Build Command

Hugo is a Go binary, not a Node.js package. The build command needs to download Hugo on the build server:

cd %path% && curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz && ./hugo --minify

Important: Use hugo_extended if your theme uses SCSS. The standard version will fail silently or with a cryptic error.

Pin the Hugo version. Hugo occasionally introduces breaking changes. Update the version in your build command deliberately, not automatically.

Set the Deployment Subdirectory

public

This ensures only the built static files are deployed — not your Hugo source code, themes, or content markdown.

Configure Your Server

  • Protocol: SSH (recommended) or SFTP
  • Hostname: Your server IP or domain
  • Deployment Path: /var/www/hugo-site/
  • Authentication: SSH key

Git Submodules for Themes

DeployHQ supports recursive submodule checkout. If your theme is a Git submodule, it's cloned automatically during deployment. No extra configuration needed.

Verify your .gitmodules file is committed: ini [submodule "themes/ananke"] path = themes/ananke url = https://github.com/theNewDynamic/gohugo-theme-ananke.git

Server Configuration (Nginx)

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/hugo-site;
    index index.html;

    # Static assets
    location ~* \.(css|js|png|jpg|jpeg|gif|svg|ico|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # HTML pages
    location / {
        try_files $uri $uri/ $uri/index.html =404;
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }

    error_page 404 /404.html;
}

No PM2 or process manager needed — Hugo sites are pure static files.

Branch-Based Environments

Branch Server Build Flag
main production ./hugo --minify --environment production
staging staging ./hugo --minify --environment staging --baseURL https://staging.example.com/

Deploy

Push a commit. DeployHQ: 1. Clones your repo (with theme submodules) 2. Downloads Hugo binary and builds the site 3. Compares public/ against what's on the server 4. Transfers only the changed files via SSH/SFTP

Edit one blog post? Hugo rebuilds in milliseconds. DeployHQ transfers ~3-4 files (the post, the list page, RSS feed, sitemap). Deployment completes in seconds.

Step 8: Troubleshooting

"TOCSS: ... this feature is not available in your current Hugo version"

You're using the standard Hugo binary instead of the extended version. Update your build command to download hugo_extended:

curl -sL https://github.com/gohugoio/hugo/releases/download/v0.145.0/hugo_extended_0.145.0_linux-amd64.tar.gz | tar xz

Theme Not Found

Ensure the theme is either: - A Git submodule (check .gitmodules is committed) - Or committed directly in the themes/ directory

If using submodules, verify the URL in .gitmodules is accessible from DeployHQ's build server.

Wrong baseURL in Production

Links and assets point to localhost or the wrong domain. Set the correct baseURL in hugo.toml or override it in the build command:

./hugo --minify --baseURL "https://example.com/"

Build Works Locally But Fails on DeployHQ

Check Hugo version mismatch. Your local Hugo might be newer or older than the version in the build command. Pin the same version in both.

Also check for OS-specific issues — if you develop on macOS but deploy from Linux, ensure your theme doesn't use case-sensitive file paths incorrectly.

Submodule Cloning Fails

If the theme repository is private, the DeployHQ SSH key needs access to both your main repo and the theme repo. Either: - Make the theme repo public - Add the DeployHQ key to the theme repo as a deploy key - Use HTTPS with embedded credentials in .gitmodules

Conclusion

Hugo's build speed is legendary, and pairing it with DeployHQ's differential deployment means your content goes live seconds after pushing. The public/ directory contains pure static files — no server runtime, no process manager, no database. Just HTML, CSS, and JavaScript served by Nginx.

For other frameworks, browse the full DeployHQ guides library.

Ready to automate your Hugo deployments? Sign up for DeployHQ — it's free for one project.

Need help? Contact us at support@deployhq.com or on Twitter/X.