This post is going to go over how to host your own Hugo site in GCP storage. I will presume you have already used Hugo before and understand the basics.

We are going to need a Google Cloud Platform account with a project set up, and we will use Cloudflare as a DNS provider for free CDN and SSL encryption. So if you haven’t already, go create accounts with them.

Resources#

DNS#

First thing’s first is that you are going to need a domain name. I personally use hover.com to get all of mine which is why I have linked them above (You can find a discount code, seemingly by listening to any podcast in the last year).

We want to set up cloudflare to be our DNS provider, so login to Cloudflare and add a new site. This will lookup your current DNS settings, and then give you instructions on changing your nameservers, i.e. in Hover, delete ns1.hover.com, ns2.hover.com and ns3.hover.com and add liberty.ns.cloudflare.com and ishaan.ns.cloudflare.com (your cloudflare nameservers may be different).

Once you have DNS set up, it’s time to let Google know that you own the domain. For this head on over to Google Webmaster and input your new domain name.

Important: use the top level name, i.e. nebloc.com not blog.nebloc.com.

Choose Hover.com as your provider, and it will give you a code that looks something like:

google-site-verification=hvACOIJoijcu30oOAICSOI2nf0jnocn

Copy all of this and head back to the cloudflare console. In the DNS menu, add a record type TXT with name @ and paste the record into the content.

Once done, go make a coffee ☕ and relax for a bit as the record propegates. After your breather, click verify, Google will check for the TXT record and you should be good to go!

The final step is to point your domain name to the storage bucket with a CNAME record. In the Cloudflare console, add a new CNAME for where you want your site, and point it to c.storage.googleapis.com.

typenametargetTTLproxy
CNAMEblogc.storage.googleapis.comAutotrue

Storage#

Once you have a domain name and Google know’s you own it, we can create a bucket that has the same name as our domain. For this you can either go to the console linked above or switch to the terminal. You will need to have the Google Cloud SDK installed.

gsutil mb gs://domain-name.com # i.e. gsutil mb gs://blog.nebloc.com

The bucket is now ready for you to upload the resulting build from Hugo! For this we need to build the site with the command hugo inside our project, and copy the resulting files to the Google storage bucket with:

gsutil -m cp -r ./public/* gs://domain.com

Where

  • -m allows it to copy files in parallel.
  • cp to use gsutil’s copy command.
  • -r to recursively copy directories.
  • ./public is the directory we want to copy.
  • gs://domain.com is the bucket we want to copy to.

The final step is to allow public read access to all the items in the bucket. This can be done with:

gsutil acl ch -r -u AllUsers:R gs://domain.com

Where

  • acl means Access Control List.
  • ch to change the ACL.
  • -r -u recursively update.
  • AllUsers:R sets the rule that all users can read the file.
  • gs://domain.com is again the bucket we want to do this on.

Done!#

You should be able to head over to your domain now and see your Hugo site in all its glory.

For convenience I like to keep the deployment commands in a Makefile with some other helpers for Hugo management.

BUCKETNAME = blog.nebloc.com

.PHONY: init build deploy dev

init: # Get theme after cloning repo
	git submodule update --init

build: init # Build hugo to public dir
	hugo

deploy: build 
	# Copy directory to bucket
	gsutil -m cp -r ./public/* gs://${BUCKETNAME}
	# Set main page to index.html and error page to 404.html
	gsutil web set -m index.html -e 404.html gs://${BUCKETNAME}

dev: init # Run dev server
	hugo -D server