We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
2018 / 01 / 28
How to set up automatic Hugo website generation and deployment with Git
Just because we can
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
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
-
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
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
We need the hugo
command available, for that the easiest way is to use snapd
:
sudo apt install snapd
sudo snap install hugo
Login as the git
user and verify hugo
is working:
sudo su git -l
hugo version
You should see something like:
Hugo Static Site Generator v0.34 linux/amd64 BuildDate:
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 master
branch 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
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"
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"
-
Try to access the web 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
You should answer
yes
—don’t just typey
— when it asks:Are you sure you want to continue connecting (yes/no)?
-
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
-
sudo chown $USER:$USER git.pub
-
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/
-
Upload the key to the server where the page is going to be hosted:
scp ~/tmp/git.pub web-server:
-
Login to the web server machine:
ssh web-server
-
Copy the contents of
~/git.pub
at the end of~/.ssh/authorized_keys
.That’s it, SSH into
git-server
, thensudo su git -l
and test thatssh webcustomer@222.222.222.222
works.If the last SSH login work, you can now
scp
orrsync
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
orscp
to transfer files fromgit-server
toweb-server
—I prefer to usersync
:
#!/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"
NOTE: You’ll need to tweak the last param for the rsync
command above to match your
website’s files path.