Google Cloud Storage has a feature where storage buckets can be used as a cost effective web server. It can only host static sites, but that works just fine for anything with all the logic on the client side.
Hosting a static website using Cloud Storage is extremely affordable.
This site is using this approach for hosting.
The official documentation can be found here.
Find the latest pricing data from Google here.
Google doesn't seem to actually charge for the static website hosting feature of Cloud Storage. Instead, it just bills you for the storage usage. Notable is that the operation usage cost will be far higher, and the data storage cost far lower than in a typical Cloud Storage use case.
These prices are rough and there are lots of edge cases:
As you can see, for anything but hugely popular sites this will usually work out to almost free.
A DNS TXT record containing a special string needs to be assigned to the domain name that will be applied to the storage bucket. This is used to confirm ownership of the domain.
To add the domain to the search console:
kyle
as the "Name" and the string from Google as the "Content". TTL Auto.The domain name can now be bound to a Cloud Storage bucket.
Note: I had a really hard time doing this with GoDaddy. The TXT change would not propagate even after over 24 hours. I transferred my domain to Cloudflare. Their updates apply basically right away!
See also: How I transferred the domain from GoDaddy to Cloudflare.
Update the subdomain CNAME record to point to Google's API URL.
In Cloudflare I made a CNAME entry for kyle.pericak.com
that looked like
this:
kyle
c.storage.googleapis.com
Go to the Google Cloud Storage Browser. Click Create Bucket up at the top.
kyle.pericak.com
The storage bucket now exists and is ready to host the static content.
Permit everyone to read the website files from Cloud Storage:
allUsers
Storage Object Viewer
Cloud Storage doesn't know where the page root is by default. Define it:
If this isn't done then the website will show XML with an error stating
Anonymous caller does not have storage.objects.list access
.
Option 1: Using gsutil:
gsutil defacl ch -u AllUsers:R gs://kyle.pericak.com
Option 2: From the web UI:
While its possible to manually upload each file using the web UI, it would be super tedious.
Run the gsutil rsync
module to upload files at all once.
Note that $dst_url
is pointing at my domain-associated cloud storage bucket.
# -r recurse - sync directories
# -c compare checksums instead of mtime
# -d Delete extra files under dst_url not found under src_url
src_url="./output"
dst_url="gs://kyle.pericak.com"
gsutil -m rsync -r -c -d $src_url $dst_url