Jekyll Static Website on Google Cloud Storage

Posted by Jen Tong on July 24, 2015

Years ago, we built websites by hand editing HTML files and FTPing them to our web server. It was painful. Content management systems like WordPress and Joomla! made authoring content easier, but with them came hosting complexity and scaling challenges. Nobody wants their site to go down on its most popular day.

Enter Jekyll. It’s like we’ve come full circle. Jekyll is a framework for generating static HTML sites. It combines the productivity of templating and markdown syntax with the simple hosting of hand edited HTML.

This blog entry goes through setting up, a Jekyll static website, on Google Cloud Storage. It also covers scripting updates.

Why Google Cloud Storage?

Jekyll outputs HTML, which you can host pretty much anywhere. You could blow the dust off of your WS_FTP CD-ROM and upload it to your ole’ web server, but there are much better options these days.

You could use GitHub pages, Firebase Hosting, Divshot, or many others. This blog post isn’t meant to be a hosting provider comparison, but here are some cool things about Cloud Storage to keep in mind:

  • Zero configuration consistent, fast delivery from global edge caches
  • Do you have a static website with terabytes of rarely accessed content? Nearline storage could save you a ton of money
  • Scales to really, really huge static websites, like many terabytes
  • Fine grained access control to individual objects
  • Do you upload a lot of video from mobile connections? The REST API has neat features like chunked multipart upload of big objects.

In any case, it doesn’t take long to try out a hosting provider. So, evaluate a few, and pick the one that fits your needs best. In the mean time, let’s get up on Cloud Storage.


Verify your domain and set up DNS

Before we can create a Cloud Storage bucket for, we need to prove to Google that we own the domain. Do this from Google Webmaster Tools. There are many ways to verify your domain. Here we’ll use the DNS method because is a brand new domain name.

  1. Log into webmaster tools with the same account you plan to use for Cloud Storage.
  2. Click ‘Add Property’ and type in your domain name.

    add property

  3. Select the ‘Alternate methods’ tab, ‘Domain name provider’, and then ‘Other’

    select dns

  4. Add the provided TXT record to your domain name and give it a few minutes to update.
  5. Since we’re already editing DNS settings, take the opportunity to add a CNAME alias that points to
  6. Return to webmaster tools and click ‘Verify’.

Set up a static website bucket on Google Cloud Storage

  1. Sign up for Google Cloud Platform, if you haven’t already. The form asks for a credit card, but don’t sweat it. Cloud Platform won’t automatically bill you; the credit card is just verify your identity. Also, new accounts get a $300 free trial. This is plenty of credit to determine if Cloud Storage is right for your project.
  2. Go to the Google Developers Console and click ‘Create Project’.
  3. From the project page, use the left side menu to navigate through Storage -> Cloud Storage -> Browser, and click the blue ‘Create bucket’ button. Name the bucket your domain name. I named mine

    Create bucket

  4. Return to the bucket list and click the bucket menu. Edit default object permissions (NOT bucket permissions) and grant allUsers read access. This makes everything we add to the bucket publicly readable by default.

    make public

  5. Click the bucket menu again, but this time select ‘Edit website configuration’. Set the ‘Main page’ to index.html and save.

Your bucket is all set up to serve a website. Time to put some stuff in there.

Initial deployment and test

Use the drag and drop features of the developer console to make the first deployment. This is an easy way to verify that everything is set up correctly.

  1. Build your Jekyll site
$  jekyll build
Configuration file: /Users/mimming/
            Source: /Users/mimming/
       Destination: /Users/mimming/
 Auto-regeneration: disabled. Use --watch to enable.
  1. Browse to your bucket on the developer console and into drag the contents of \_site on to the page.

    drag and drop to deploy

  2. Once the upload finishes, visit the website.
  3. Celebrate a successful initial deployment.

Automate deployments

It’s cool that you can drag files on to the bucket browser, but we’re real developers. We want something we can automate. This is where scripting uploads with the Cloud SDK comes in handy. We could hack up a quick shell script, or integrate it with a build system like gulp.

Shell Script

  1. Install the Cloud SDK using the instructions for your platform.
  2. Authenticate your SDK
$ gcloud auth login
  1. Use gsutil to upload your content. It has a bunch of commands, but stick with rsync for now.
# -m use faster multithreaded uploads
# -d delete remote files that aren't in the source
# -r recurse into source subdirectories
$ gsutil -m rsync -d -r . gs://
  1. Wrap these commands in a tiny shell script. I call mine
jekyll build &&
gsutil -m rsync -d -r ./_site gs://
  1. Run, see changes go up to the cloud, and celebrate the upload of another dinosaur picture.


Some of us are build system hipsters. If you’re cringing at the thought of a directory of utility shell scripts, you’re probably already using gulp.js to build your Jekyll site. If you’re not, you should channel your node.js mojo and check it out.

It turns out that gulp.js plays well with the Cloud SDK. Add a deploy task to your gulpfile.js:

var gulp = require('gulp');

gulp.task('deploy', function() {
  var spawn = require('child_process').spawn;   
  var jekyll = spawn('jekyll', ['build'], {stdio: 'inherit'});

  jekyll.on('exit', function(code) { 
    if(code === 0) {
      require('child_process').spawn('gsutil',  ['-m', 'rsync', '-r', '-d',
'./_site', 'gs://'], {stdio: 'inherit'});
    } else {
       process.stdout.write("Build failed. Exit code: " + code);

Run gulp deploy. See more changes go up. Celebrate a world with even more dinosaur pictures.

Note: The weird callback thing is in there because we’re chaining child processes. It tells gulp to wait for Jekyll to exit successfully before attempting to push to Cloud Storage. You can learn more about this pattern in the gulp.js reference docs.


And just like that another dinosaur themed blog is on the Internet, and this one is backed by Cloud Storage. You created a bucket, configured it to serve public web traffic, and uploaded content. Then you crafted some scripts to make publishing updates easier. And, you celebrated dinosaurs a little along the way.

If you have questions or comments, please tweet at me =]