Auto Deploy: Hugo + GIT

Giang L. Nguyen

December 8, 2019

I always wanted to automate my way of deploying, just like codes are being deployed with jenkins, puppet or ansible. So I figured out, why not try to automate my way of deploying my website as it taking huge amount of time to upload and take care of some action after the files has been uploaded.

Since I’m using Hugo to generate my page and GIT to have revision control of my page, I will try to combine them. Since git and hugo has a huge community, I believe you can find alot of information on the google search-engine.

Here is what I was doing before

  1. Creating the website locally
  2. Testing and push revision changes to git
  3. Using hugo to generate the files for production
  4. Connect to webserver
  5. Upload the generated files
  6. Change folder target for the website

Here is what I want it to go

  1. Creating the website locally
  2. When done

What I’m using in this project

Requisite

Pulling the website to your developer desktop

First of all, I need to pull the project from the main repo. server to my local developer desktop, by adding the repo and pull it.

# Staying in my home-folder
git remote add origin git@<ip>:<repofolders>.git #ex git@github.com:mygit/project.git
git pull origin master #pull the project down to project-foldername, ex. if you downloaded project.git, it is going to pull down to the project/ folder.

Now we have the file locally at our desktop, lets setup our webserver to receive our changes and deploy the web with hugo

Webserver

My webserver is setup per webpage base and the nginx proxy is redirecting the cname to the ‘www’ folder in users home folder on the server, my cname is ‘vi3t.net’ and username ‘vi3t’.

nginx config
server_name vi3t.net;
...
location ~ ^/~(.+?)(/.*)?$ {
        alias /home/$1/www/$2;
...
Creating a bare git
# Staying in my home-folder
git init --bare <foldername>.git #ex git init --bare myweb.git

# creating hook file for doing something when receiving file
touch <foldername>.git/hooks/post-receive
Creating hooks for git

I’ve been keeping the echo’s and comments for feedback when doing push and for you to be able to see what the script is doing.

vim <foldername>.git/hooks/post-receive # editing the file

#!/bin/sh
stage=/home/vi3t/temp-www # change your folder accordingly
git=/home/vi3t/<foldername>.git # change your folder accordingly
prod=/home/vi3t/www # change your folder accordingly
release=/home/vi3t/release # change your folder accordingly
date=$(date +'%Y%m%d-%H%M')
deploydir=$release/vi3tnet/$date # change your folder accordingly

echo "* Does folder exist? Creates if not.."
if [ ! -d $stage ]; then
    mkdir -p $stage || echo "Sucessfully created folder " $stage;
else
    echo $stage" exists. Folder not created. Stopping script";
    exit 1;
fi

echo "* Git checkouts"
git --work-tree=$stage --git-dir=$git checkout -f master --force
cd $stage
git --work-tree=$stage --git-dir=$git submodule init #workaround - pulling submodules if exists
git --work-tree=$stage --git-dir=$git submodule update --init --recursive --force #workaround - pulling submodules if exists

#Deploy
echo "* Deploying.."
if [ ! -d $deploydir ]; then mkdir -p $deploydir; echo "Deploy directory created: " $deploydir; fi;

echo "** Hugo doing work from " $stage " to " $deploydir
echo "*** Hugo output start ***"
hugo -s $stage --cleanDestinationDir --minify -d $deploydir
echo "*** Hugo output stop ***"
echo "** Linking folders.."
rm -rf $prod
ln -snf $deploydir $prod
echo "Succesfully deployed. Cleaning working folder " $stage ". Working dir is " $deploydir
rm -rf $stage 

Pushing changes to prod

Now that our webserver is ready to receive files, lets try to do some changes by making a file and push the change.

git remote add prod vi3t@<host>:/home/vi3t/<foldername>.git/
hugo new blog/post.md # creating a new post with hugo
vim content/blog/post.md # changing your draft from true to false, or this post wont be visible 
git commit -a -m "new blogpost" # adding to git to push
git push prod master # pushing to our production webserver

If you are using the same script, your output should be displaying something like this

auto-deploy-output

Remember to change your draft status to false.

draft-status