The Hugo manual provides a good introduction to automated deployments via Wercker but focuses on deploying to Github pages. After some trial and error, I’ve built a good setup for deploying to a Digital Ocean droplet.
If you’re looking for background information, read the Software section. For the instructions, skip ahead to Procedure.
Hugo is a static blog generator written in Go. Like Jekyll, Hugo processes a directory of Markdown-formatted posts and generates HTML output. I am using Hugo 0.13 at time of writing, but later versions should work similarly. After originally hosting this blog with Wordpress, then Ghost, I have found Hugo to be much faster (because of its static nature) and the easiest to self-host. Documentation is excellent and the project frequently adds new features. If you haven’t given Hugo a try, I highly recommend giving it a try. Between Hugo and Github Pages, it’s never been easier to create and host a good-looking site for free.
I have a Digital Ocean droplet left from my time hosting Wordpress and Ghost blogs, so I decided to host this blog on Digital Ocean instead.
Hosting the source code
This website’s source code is hosted on Bitbucket. GitHub is an equally good choice for hosting the Markdown files that Hugo will parse; it comes down to a matter of personal preference. When creating a repository, I recommend keeping it public to make integration with Wercker easier.
Digital Ocean is the backbone of this website. The server runs Nginx on Ubuntu 14.04 x64 to serve HTML pages generated by Hugo to visitors. This post assumes you have already set up a droplet with a working web server; if you have not, Digital Ocean provides excellent guides to get you up to speed. For security reasons, I recommend providing a public key to Digital Ocean and private-key authentication for login and never setting a root password.
Wercker is a platform for building and deploying applications. In this case, we will be using Wercker to build and deploy the application.
If you already have a Digital Ocean droplet set up, continue to the next
paragraph. If not, hold off until after creating a new Wercker application; you
will be able to create a new droplet with Wercker’s SSH key already populated in
Next, make sure Hugo works. The
Hugo quickstart includes instructions
for installing Hugo and running a simple site from your local machine. After
ensuring that Hugo builds the website correctly with
hugo server --theme=herring-cove (assuming that you have cloned the
herrive-cove theme and placed it within your Hugo directory), add a new file to
the base directory called
wercker.yml. This file will provide Wercker with all
the information it needs to build and deploy your website to Digital ocean.
Inside the file, paste the following lines:
box: wercker/default build: steps: - email@example.com: version: 0.13 theme: <YOUR_THEME> flags: --buildDrafts=false deploy: steps: - add-to-known_hosts: hostname: $HOSTNAME - mktemp: envvar: PRIVATEKEY_PATH - create-file: name: write key filename: $PRIVATEKEY_PATH content: $WERCKER_PRIVATE overwrite: true - script: name: remove old files code: ssh -i $PRIVATEKEY_PATH -l root -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $HOSTNAME rm -rf /var/www/blog/* - script: name: transfer blog code: | scp -r -i $PRIVATEKEY_PATH public/* root@$HOSTNAME:/var/www/blog ssh -i $PRIVATEKEY_PATH -l root -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $HOSTNAME chown -R www-data:www-data /var/www/ - script: name: restart nginx code: ssh -i $PRIVATEKEY_PATH -l root -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $HOSTNAME service nginx reload
<YOUR_THEME> with the name of whichever theme you are using. If you
are using Apache instead of Nginx, you will also need to change the final line
to reload Apache. This file includes both configuration for Hugo (theme, whether
to build drafts, and version) and Wercker instructions. Push the directory to
the code-hosting service of your choice.
Now create a new application with Wercker. The steps are:
- Create -> Application
- Choose Git provider: whichever one you are hosting your files with
- Select your blog from the repository list
- Select owner: yourself
- Configure access: Check out without SSH key (this is why the blog’s code should be set to public).
- Setup your wercker.yml: Choose “I already have a wercker.yml”
Open the settings for your new application. By this point, Wercker is able to detect changes you make to your blog when you push the new posts to GitHub/ Bitbucket but is able to deploy the built website to Digital Ocean. Time to change that.
In the application settings, generate a new SSH key (SSH keys -> Generate new key pair). Name it something memorable to use later. Wercker will hold onto the private key and give you a public key for copying. Copy the public key to your clipboard.
If you already have a Digital Ocean droplet you will use, SSH into the droplet
as root (
ssh root@your-droplet-ip and edit
the public key that Wercker generated for you, save the file, and exit.
If you have not yet created your droplet, open your Digital Ocean settings and add a new SSH key (located under Settings->Security). Now create a new droplet and add the SSH key to it during creation, in addition to your own public key, so that both Wercker and you can log in. Install Nginx on the server and make sure that it works, then continue.
Still in application settings, open the Deploy targets tab. Choose Add deploy
target -> Custom deploy and give it a name. Select auto deploy successful
builds to branch(es) and enter
master for the branch name. Then add 2
variables to the deploy pipeline.
- Name the first variable
WERCKERand choose SSH Key pair. Select the key pair you earlier generated and added to your Digital Ocean droplet. You will notice two variables generated,
WERCKER_PRIVATE. These correspond to the keys in
- Name the second variable
HOSTNAMEand choose Text. In the text box, put the IP address or hostname of your Digital Ocean droplet.
Save the new settings. Now everything should work!
Wercker should have built your website after you set up the application. Open the application and navigate to the Builds tab. Find the latest build and open it. At the top there is a Deploy to button. Click it and deploy to the Digital Ocean droplet you just added in Deploy targets. Wercker will take care of transferring your website’s files to Digital Ocean via SSH and reloading Nginx to make sure that the changes take effect.
Congratulations, you’re hosting your own website!
- Wercker has been experimenting with a infrastructure stack built on Docker. This post was written with the old infrastructure stack in mind. If given a choice, choose to use the old stack (v1). The wercker/default box is not available when using the Docker-based infrastructure.
- If the website looks like it’s missing a theme, make sure that the theme you have used on your local machine is part of your git repository and has been synced to Bitbucket/ GitHub. This has been the source of almost all my recent build/ deployment errors.
- If a post isn’t appearing, make sure that it isn’t set to be a draft.
- Thanks to the Hugo automated deployment guide for the basis of this post.
- And a big thanks to Hugo, Wercker, and Bitbucket, for providing the software
that turns this from a lengthy process into one step of