DEV Community

Cover image for How to setup automatic Hugo website generation and deployment with Git
Víctor Adrián
Víctor Adrián

Posted on • Originally published at lobotuerto.com on

How to setup automatic Hugo website generation and deployment with Git

Let’s say that you have tried Hugo, you liked it, and made a website with it.

Now you are ready to deploy that website for the whole world to see.

Wouldn’t it be great if you could just do:

git add .
git commit -m "Updated blog content"
git push
Enter fullscreen mode Exit fullscreen mode

And be done with it?

Well, if that sounds like your kind of thing; something you’d like to have…

Then read on my friend!


Inventory

What do you need for this tutorial?

  • A public server somewhere. If you don’t have one, you can get a VPS (Virtual Private Server) from Linode, DigitalOcean or similar providers.
  • An account with access to sudo.
  • You have git available, from this guide.
  • You use Gitolite to manage your repositories, from this guide.
  • A configured webserver —I recommend looking into NGINX, since it’s super easy to setup in Ubuntu.

Let’s assume:

● A local ~/.ssh/config file with this content:

Host git-server
  # This is the IP for your VPS
  HostName 111.111.111.111
  Port 22
  # This is the remote user
  User yolo

Host web-server
  # This is the IP for your other VPS
  HostName 222.222.222.222
  Port 22
  # This is the remote user
  User webcustomer
Enter fullscreen mode Exit fullscreen mode

● You have your Hugo project versioned with git and you can push code to the remote repository.

● The repository’s name is yolo-web, so you can clone it like this:

git clone git@git-server:yolo-web
Enter fullscreen mode Exit fullscreen mode

Install dependencies

First, let’s login on the remote machine; the one you want to setup automatic deployment on.

Open a terminal and SSH into it:

ssh git-server
Enter fullscreen mode Exit fullscreen mode

We need the hugo command available, for that the easiest way is to use snapd:

sudo apt install snapd
sudo snap install hugo
Enter fullscreen mode Exit fullscreen mode

Login as the git user and verify hugo is working:

sudo su git -l
hugo version
Enter fullscreen mode Exit fullscreen mode

You should see something like:

Hugo Static Site Generator v0.34 linux/amd64 BuildDate:
Enter fullscreen mode Exit fullscreen mode

Create and configure the post-receive hook script

This is the important part.

This script will be in charge of doing something after the repository receives a git push.

In our case, we want the script to git checkout a copy of the current masterbranch in a directory of our choosing and then call hugo on it to generate the HTML files for the web server.

Let’s create the post-receive file:

touch ~/repositories/yolo-web.git/hooks/post-receive
chmod 700 ~/repositories/yolo-web.git/hooks/post-receive
Enter fullscreen mode Exit fullscreen mode

And put this content inside:

#!/bin/bash

export GIT_WORK_TREE=/home/git/yolo-web-compiled

echo `pwd`
echo "Generating site with Hugo for yolo-web"

mkdir -p $GIT_WORK_TREE
chmod 755 $GIT_WORK_TREE

git checkout -f master

rm -rf $GIT_WORK_TREE/public
cd $GIT_WORK_TREE && /snap/bin/hugo

find $GIT_WORK_TREE/public -type f -print | xargs -d '\n' chmod 644
find $GIT_WORK_TREE/public -type d -print | xargs -d '\n' chmod 755

echo "All done! 0 problems"
Enter fullscreen mode Exit fullscreen mode

You now have a process in place that will leave the latest HTML files generated by Hugo in /home/git/yolo-web-compiled.

Go ahead, try it out, make some local changes, git commit and git push, then SSH in and see what’s inside /home/git/yolo-web-compiled.

The web server situation

Same server for compiling and web serving

If your web server is in the same machine as your repos, then you can simply point with a symbolic link to the /home/git/yolo-web-compiled/public directory and call it a day!

Else…

Compiling in one server, web serving in another

What if you have different machines for hosting your Git repositories and hosting your web pages?

How would that work? Glad you asked...


What follows is an opinionated soluion to this problem.

● Generate an SSH key pair for the git@git-server user with an empty passphrase:

ssh git-server
sudo su git -l
sshkey-gen -t rsa -b 4096 -C "git@git-server"
Enter fullscreen mode Exit fullscreen mode

● Try to access the server through SSH —it’ll fail, but we need this so its signature gets registered into the ~/.ssh/know_hosts file.

ssh webcustomer@222.222.222.222
Enter fullscreen mode Exit fullscreen mode

You should answer yes ---don't just type y--- when it asks:

Are you sure you want to continue connecting (yes/no)?
Enter fullscreen mode Exit fullscreen mode

exit the git user shell, you are now in your yolo shell.

● Copy the public key from git to your home:

sudo cp /home/git/.ssh/id_rsa.pub ~/git.pub
Enter fullscreen mode Exit fullscreen mode

exit the remote session, you are now in your local machine.

● Copy the git.pub file to your local machine:

mkdir ~/tmp
scp git-server:git.pub ~/tmp/
Enter fullscreen mode Exit fullscreen mode

● Upload the key to the server where the page is going to be hosted:

scp ~/tmp/git.pub web-server:
Enter fullscreen mode Exit fullscreen mode

● Login to the web server machine:

ssh web-server
Enter fullscreen mode Exit fullscreen mode

● Copy the contents of ~/git.pub at the end of ~/.ssh/authorized_keys.

That’s it, SSH into git-server, then sudo su git -l and test thatssh webcustomer@222.222.222.222 works.

If the last SSH login work, you can now scp or rsync content from the repository machine to the web server machine!

● Modify the ~/repositories/yolo-web.git/hooks/post-receive file and include a call torsync or scp to transfer files from git-server to web-server —I prefer to use rsync:

#!/bin/bash

export GIT_WORK_TREE=/home/git/yolo-web-compiled

echo `pwd`
echo "Generating site with Hugo for yolo-web"

mkdir -p $GIT_WORK_TREE
chmod 755 $GIT_WORK_TREE

git checkout -f master

rm -rf $GIT_WORK_TREE/public
cd $GIT_WORK_TREE && /snap/bin/hugo

find $GIT_WORK_TREE/public -type f -print | xargs -d '\n' chmod 644
find $GIT_WORK_TREE/public -type d -print | xargs -d '\n' chmod 755

rsync -avzP $GIT_WORK_TREE/public/ \
webcustomer@222.222.222.222:/var/www/yolo-web/html

echo "All done! 0 problems"
Enter fullscreen mode Exit fullscreen mode

NOTE: You’ll need to tweak the last param for the rsync command above to match your website’s files path.

Discussion (2)

Collapse
_justirma profile image
Irma Mesa

Love Hugo. Great post!

Collapse
lobo_tuerto profile image
Víctor Adrián Author

Indeed! It's been a wonderful experience learning it!

I intend to write a tutorial on how to create a theme from scratch (well, using only Bulma for the starting CSS).