static websites with hugo on google cloud storage

Static Websites with Hugo on Google Cloud Storage

Make Things, Show Things

If you want to put some content on the web, the fastest and easiest way is to write simple HTML. If you were making web pages 20 years ago you started with “vi index.html”.

Today websites are a lot more complex. They are often dynamically built using a database, assembled quickly for each request, and are, in general, quite a bit more complicated. This gives web pages far more capabilities but often at the expense of performance, security, and maintainability.

If you wanted to just get something (say, a blog post) out there quickly, consider a static site generator. A static site generator will usually offer some nice features (templating, themes) without the maintenance drag of something like WordPress (database migrations, security vulnerabilities). In addition, we can then host our site on very inexpensive cloud storage services.

In this post I’ll describe a basic setup using Hugo, a static site generator written in Go. We will deploy our site content to Google Cloud, specifically Google Cloud Storage.

Setup Hugo

Instructions assume you are running OSX 10.10 Yosemite.

We will need to install Go. If you have Homebrew installed:

brew install go

If you do not, or prefer to use a package, head to Go Downloads and look for the appropriate package. It should be in bold.

Next we will install Hugo.

brew install hugo

Or, get the Darwin/AMD64 package from Hugo Releases and extract it to /usr/local/bin/

Typing both “go” and “hugo” at a shell prompt should produce some output. A helpfile in the case of “go”, a config error for “hugo”. If you get “command not found” try opening a new Terminal to ensure any new environment paths are loaded.

Now lets make a directory for Hugo to work in, and tell Hugo to make a new skeleton site there:

mkdir ~/website
hugo new site ~/website

Inside here you will see the bones of your website. Let us add our first piece of content.

hugo new

In the content directory you will see Edit the file, changing the value of draft to `false’. Then write a little about yourself after the +++ block. You’re writing Markdown! Just plain text fine is for now, but feel free to get fancy with more advanced Markdown syntax. (If anyone asks, Hugo uses GitHub Flavored Markdown. Together with Markdown Basics it should get you on your way to formatting and marking up text.)

We also need to download and apply a theme. Hugo does not come with any themes. To download them we are going to clone a repository that has a bunch of premade themes. From your working directory:

git clone --recursive themes

One more thing we have to do before letting Hugo loose on our content: we have to tell it the base URL of our site so it knows the realtive paths of the files. Edit config.toml and set baseurl with:

baseurl = ""

or whatever your URL is.

With just the above steps we are now ready to build our site. Hugo has a neat built-in web server that will let us see our content. To build our site and start the server:

hugo server --theme=hyde

Note: I chose the ‘hyde’ theme but you could choose any other theme in the ‘themes’ directory. We simply need one, any one, in order to make our content visible.

Hugo will tell you that your site is available at http://localhost:1313/ Try it now.

Website Screenshot

Hopefully your content has more substance than “wheeeeeee”!

Google Cloud Storage

Now we need to push these files to Google Cloud Storage. We’ll download and configure the SDK, a tool to help use configure and deploy resources. Then we’ll point our DNS to Google with a CNAME. Finally we’ll create & configure a bucket in Google Cloud Storage, and push our new website content to it.

First install the Google Cloud SDK:

curl | bash

If curl | bash gives you the heebie jeebies you can find alternative install methods at

Note You will need a Google Cloud account with billing enabled. If you don’t have one yet head to ([] and signup for a free trial.

Start a new shell and then login following the prompts:

gcloud auth login

(Note: Before proceeding we’ll have to prove to Google we own the domain that our website will live at. If you haven’t done this before, follow the instructions at

After successfully authenticating (and verifying domain ownership) we will need to point our DNS to Google. This is done with a single CNAME record. If your website is going to be at, then the record we will create is:

blog		CNAME

This new should record should be available very quickly (since there were no records to cache), but it may still take some time if you have a negative response cached. Try sites like DNSstuff or DNSgoodies check for propagation of your CNAME.

Now we will create a bucket that has the same full name as the CNAME we just made. In our case we would create a bucket named “”

gsutil -m mb gs:// -p foo-bar-123

Your resources in Google Cloud are divided into groups called projects, and most gcloud commands require a project to be specified. Unfortunately it appears projects cannot be created from the command line so we will need to login to the and create one. Do that now and name it something like “Static Website”. I’ll assume the project ID assigned (or you chose) is foo-bar-123.

Now that have a cozy bucket in the cloud for our content we can copy all our files there. All of the content Hugo generated for us is in the public subdirectory of our working directory. Let’s upload it now:

gsutil -m cp -r public/* gs:// -p foo-bar-123

The -m flag parallelizes the upload using multiple connections.

The files we have placed in the bucket also need to have their “public” flag set. After all, we want people to see our website:

gsutil -m acl ch -r -u AllUsers:R gs:// -p foo-bar-123

We have just two more configurations to apply to our bucket, and they both involve telling it to behave like a web server. The bucket needs to know what the default filename to serve up in a directory (that is, if a user went to or Most people set this value to “index.html”. The bucket also needs to know what to serve up (colloquially, a “404 page”) when a resource is requested that does not exist.

gsutil web set -m index.html -e 404 gs:// -p foo-bar-123

Note: If you get tired of specifying the project each time you can set it with:

gcloud config set project foo-bar-123

You should now be able to see your website at If it isn’t working check out some the troubleshooting steps at


Your website should now be up and running. You might have noticed it loads lightning fast. Granted, our website is extremely simple, but one of the reasons for this is Google replicates your data to each of its datacenters, effectively giving you a CDN for free. Using a tool like shows my website is only 14 milliseconds from Cologne, Germany but also 14 milliseconds from Chicago, Illinois, USA. Your site is safely stored everywhere Google has a datacenter, and is served from more than 70 edge caches, just like Google’s website. That’s more than AWS and CloudFront.

Your website is also more secure by the sheer fact that there is no database, no PHP or any other language to exploit, and overall much less complicated. Security people would say your site has a smaller “attack surface”.

Lastly, your hosting bill just went down to pennies. This website typically costs less than $0.50 per month.


Hope this short guide got you started on hosting your static website on Google Cloud.

Thanks to Julia Ferraioli for reading drafts of this document.

Tags// , ,
More Reading
Older// Introduction