continuous deployment of a website with hugo and codeship

As you can see we’ve updated our website a little bit, and now its built using a continuous deployment pipeline with a mixture of github, codeship and rsync


Hugo is a great static website templating engine, which builds a website by combining content and layout. Its a really nice way to allow a lightweight separation of concerns between content creators and website designers.

Creating a hugo site is a little beyond the scope of this article, but there are plenty of links on the main hugo site. The main point of hugo is that it’s really nice and flexible, and it is fast - generating an entire website from source will take about 100ms, including all various indexes, pagination and so on.

If you have a very large site, it may take a tiny bit longer, but in general, its quite quick…

Hugo + Codeship

Codeship is a build service that can link in with github to build your site after every check in.

It requires a little bit of configuration to create the build. There are various ways to do this, but I prefer to have a single script that just works…

We’ll need to make the script get hold of all the dependencies, and create the website. Luckily this is pretty straightforward, as hugo is just a single executable.

Here’s the contents of our

set -x
set -e

rm -rf ./hugo_0.18_linux_amd64

curl -L | tar zxf -


$HUGO version

This downloads a copy of the hugo executable, installs it to the local directory and runs it. You may wish to check the checksum, or store a copy of hugo that you built yourself in S3 and use that

This will create your website in a directory public.

To make this work in codeship, create a project, get it connected to your github repository, and use the following as the ‘test pipeline’

cd ~/clone

Deploying the site

We can use a very simple deployment mechanism to deploy the site, with rsync. Using a codeship deployment script… note that here we are rsyncing to / - the root folder

rsync -av -e "ssh -p 12345" --no-p --omit-dir-times ~/clone/public/

Here we’ve specified that our ssh server is running on a non-standard port, 12345. Even though this is just security by obscurity, many fewer people perform rigorous portscans to find the ssh port.

Now, we don’t really want to open up a full ssh connection just to rsync, so we can secure this just a little bit more by using rrsync - or restricted rsync.

The key that you need to allow access to is specified in the codeship “General Project Settings”, under “SSH Public Key”.

This is configured by setting up a special command section in your ~/.ssh/authorized_keys file:

command="$HOME/bin/rrsync /data/website",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-ed25519 AAAAblahblahblah keyname@keyhost

The rrsync program is distributed with rsync, normally packaged as rrsync.bz2. The second parameter is the top-level directory that the rsync program is allowed access to, hence the / in the original rsync command. You can copy the rrsync program into the deployment users $HOME directory.

Please do make sure that your sshd server is suitable secured before allowing access! - Information on how to do that will be posted here soon.

Speedy deploys

As github calls a web-hook to codeship, and the hugo build is so quick, and the rsync only copies across changed files, the entire process from check-in to new website can be achieved in about 30 seconds - with full versioning and history.

comments powered by Disqus