How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04.

Mohammed Naser

Mohammed Naser

Hugo is an open source static site generator. Static site generators build a web page the moment you’re creating or editing new content. It comes with a watch mode that automatically refreshes web pages when editing them. Hugo was started as a side project by Steve Francia and today its community has more than 165 contributions, 35 themes and thousands of users. The biggest advantage of using static is that the websites are incredibly fast especially when compared to sites that carry all the burden of a heavyweight content management system.

In our previous article we wrote about Installation of Hugo on Ubuntu 14.04. Now in this tutorial we are going to deploy a Hugo site for production with Git Hooks using Ubuntu 14.04.


In order to deploy Hugo site on production, you must first setup your development server with Hugo on Ubuntu 14.04. Then build a new production server with Ubuntu 14.04 installed. Once you have access to both development and production servers, perform the following tasks to achieve your target deployment on Hugo Site with Git Hooks.

SSH Key Authentication

First of all we are going to setup a SSH key authentication between development server (on which we have already installed Hugo) and the product server on which we will be setting up the production site with Git Hooks.

Let’s run the command below to check if there’s already a key pair placed or not.

kash@pre-ubuntu:~$ ls ~/.ssh/id_rsa

If it shows no such file on directory, run the command below to generate a new ssh key.

kash@pre-ubuntu:~$ ssh-keygen

Choose the file where you wish to save the key other than the default location. Then use the command below to copy this key to your production server.

kash@pre-ubuntu:~$ ssh-copy-id ubuntu@production_server_ip 


After providing the right user credentials you will see the following output.

Number of key(s) added: 1

Now try logging into the machine, with:
“ssh ‘ubuntu@′”
and check to make sure that only the key(s) you wanted were added.

Let’s run the command on your production server from the development server.

kash@pre-ubuntu:~$ ssh ubuntu@ hostname


So, this time it won’t ask you for the password.

Initial Git Repo Transfer

In order to setup the ‘post-receive’ hook on the production server in the near future, we need to transfer an initial clone of our Hugo repository to the production server. To do this, first we will create a bare repository from our main Hugo repository in the ‘/tmp’ directory. Bare repository is a special ‘git’ repository with no working directory. So, to create this copy we will use the ‘git clone’ command using the ‘–enable’ option as shown.

kash@pre-ubuntu:~$ git clone --bare ~/hugo_web /tmp/hugo_web.git 

Then copy this bare repo to the home directory of your Production server user using the command as shown below.

kash@pre-ubuntu:~$ scp -r /tmp/hugo_web.git ubuntu@prod-server_ip:


Adding Git Remote For Production

Let’s add the git to the remote production server as a tracked remote repository using its bare repo. This will allow us to push new content to our production server easily.

Now change your directory to Hugo website and then run the command to give name to the remote as ‘prod’ and specify the connection information and location to the bare repository on the remote system.

kash@pre-ubuntu:~$ cd hugo_web/
kash@pre-ubuntu:~/hugo_web$ git remote add prod ubuntu@prod_server_ip:hugo_web.git

Setup Production Server

So far we have successfully configured our development server, now we are going to setup our production server by following some steps to install a few basic packages. Hugo installation then will create ‘post-receive’ script to deploy new content pushed to our repository.

Installing Packages on Production Server

We need to install Git, Pygments and Nginx server packages on our production server. The ‘Git’ software will be used to receive pushes and to execute our deployment script. Then we need to install ‘Pygments’ for syntaxt highlighting and ‘Nginx’ as the web server that will make your contents available for the visitors.

Let’s run the following command to update your Ubuntu server with the latest updates and patches.

$ sudo apt-get update


Then run this command to install ‘git’, ‘nginx’ and ‘python-pip’ packages.

$ sudo apt-get install git nginx python-pip

Press ‘Y’ key to proceed with the installation process. Once these packages are installed, execute the command below to install Pygments using ‘pip’ command.

$ sudo pip install Pygments


The pakages have been installed. Now we can test if we have setup the remote repository correctly on our pre-prod development machine using the following command in the Hugo project directory.

kash@pre-ubuntu:~/hugo_web$ git ls-remote prod

Installing Hugo on Production

Now we are going to install Hugo on the production server using the same way we did in our previous article to install and use Hugo on Ubuntu 14.04 (production).

Run the following command to download the latest hugo package and then install using ‘dpkg’ command as shown in the image.

$ wget https://github.com/spf13/hugo/releases/download/v0.15/hugo_0.15_amd64.deb
$ sudo dpkg -i hugo_0.15_amd64.deb


For confirmation run the command below to check the version of your Hugo installation.

$ hugo version

Now clone Hugo themes directly from Github into your home directory by executing the command below.

$ git clone --recursive https://github.com/spf13/hugoThemes ~/themes

Nginx Configuration to Serve Production Files

Here we will be configuring the Nginx web server to serve the files produced during the deployment. To do so we will create a new directory in our user’s home and then configure the default configuration file of Nginx to make a few adjustments.

$ mkdir ~/public_html
$ sudo vim /etc/nginx/sites-available/default

Make sure that you have changed the document root path and server name according to your server IP address or domain name.

Then restart Nginx services, so that the changes will be applied.

$ sudo service nginx restart

Creating Post-Receive Hook to Deploy Hugo Site

In this step we will be ready to work on post-receive hook deployment scripts by creating a new file in the ‘hooks’ directory present in the bare directory of our production server.

Change your directory to the ‘hooks’ and create a new file and put the following contents in it as shown below.

$ cd hugo_web.git/hooks/
ubuntu@pro-ubuntu:~/hugo_web.git/hooks$ vim post-receive



set -e

trap "echo 'An issue has been occurred.  Reverting to backup.'; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY" EXIT

rm -rf $PUBLIC_WWW/*
/usr/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b "http://${MY_DOMAIN}"
trap – EXIT

In this file, after indicating the bash script, we have setup the ‘git_repo’ to our bare repository. Then, mention the ‘Working_Directory’ to clone this bare repository, while the ‘Public_www’ variable and backup web folder will be kept accessible through the ‘Backup_www’ variable.

One thing that you should keep in mind is to change ‘My_Domain’ parameter with your production server’s IP. In the second part of the script, use a bash command, ‘set -e’ to exit immediately in case of any error.

In the last part of our script we have used the ‘trap’ command, so that in case of deployment failure the trap command will restore our backup copy to the web document root directory.


After completing the file configuration, use below command to give it executable permissions.

ubuntu@pro-ubuntu:~/hugo_web.git/hooks$ chmod +x post-receive

Testing Deployment System

This is the last step to test our production deployment system after completing the configurations. To do so, simply execute the bash script that we created in the previous step.

ubuntu@pro-ubuntu:~/hugo_web.git/hooks$ bash post-receive

Cloning into '/home/ubuntu/hugo_web-working'...
0 of 2 drafts rendered
0 future content
2 pages created
0 paginator pages created
0 tags created
0 categories created
in 17 ms

Now you can open your web browser by giving the IP or FQDN of your production server to see the same contents you have configured in your pre-prod server.

If you wish to add some more content, go back to your development server and run the command below to add a new post.

kash@pre-ubuntu:~/hugo_web$ hugo new post/Testing-Deployment.md

A new file will be opened in your default editor, so put some new contents and close the file after saving the changes. Then run the following commands to add the contents to git and commit the changes.

kash@pre-ubuntu:~/hugo_web$ git add .
kash@pre-ubuntu:~/hugo_web$ git commit -m 'Deployment test'

Now run the following command to deploy the new contents on the pre-prod to the production server.

kash@pre-ubuntu:~/hugo_web$ git push prod master


Now visit your production server’s IP address in your web browser. You will be glad to see your new content in your web browser.


Hugo has proven to be reliable as well as scalable. It might be your go-to-tool when you start working on your next project on the web. So far, in this article, we have deployed the Hugo site on production server using its integration with the pre-prod server. Every step is simple to understand while working on Hugo, proving it to be one of the best tools to be used for web deployment. It can parse your content according to supplied requirements to generate consistent web pages that can easily be hosted on any web server or host by applying any of your favourite theme to it.

Would you like to know about Zuul, a CI/CD project gating tool? Download our white paper and get reading!

How to up your DevOps game with Project Gating

Share on Social Media:


Cluster API driver for OpenStack Magnum

Mohammed Naser

Public Cloud

9000 MTUs (jumbo frames) in all Public Cloud Regions

Mohammed Naser


OpenInfra Summit Berlin 2022 VEXXHOST Recap

Mohammed Naser

Go to Top