Google Cloud Platform (GCP) Content Delivery Network (CDN) Cache Control Script and Compression

Google Cloud Data Center If you are, like me, building websites using Google App Engine, you may be interested in using Google Cloud Platform Content Delivery Network to host static files to improve your website performance. There are a number of steps required to configure CDN using a storage bucket for your assets. Below I will walk through the required steps to create a storage bucket backed CDN solution which includes a load-balancer which is required for SSL support.

SSL Configuration

Unlike the automatically generated SSL certificates supported by App Engine CDN / Load Balancing requires you to provide your own SSL certificate. If you are using a provider like NameCheap then the first step is to create a key and certificate signing request. Using the Certificate Signing Request you can request a certificate from your SSL provider of choice. After the usual verification of email address you will typically end up with a certificate file. This can then be used by the create certificate resource tool.

1. Create your certificate

openssl genrsa -out my-private-key.key 2048

2. Create your certificate signing request

openssl req -new -key my-priavate-key.key -out certificate-signing-request.csr
Once you have your certificate signing request you will paste it into your SSL provider's site to start the signing process. Once your respective domain validation is done you will be sent your certificate. Save it into my-certificate.cert to continue below.

3. Upload your certificate

gcloud compute ssl-certificates create certificate-name --certificate my-certificate.cert --private-key my-private-key.key

Create your CDN resource

Once you have your SSL certificate imported using the gcloud tool you can go through the setup to create your CDN resource. There are a few configuration options to take into consideration
  • When you create a new origin you will need to create a new load balancer for it.
  • Backend Confguration: create a new storage bucket. Make sure it is CDN enabled.
  • Host path rules: You should configure your custom host and path rules to your host like cdn.yourdomain.com and path /* to match all content.
  • Frontend configuration: You will pick the HTTPS protocol, network service tier premium, create a static IP, select the certificate you uploaded above.
Make a note of the IP address of your load balancer once it is created or refer to the address list in your account.

Enabling Gzip Compression during upload

To enable GZIP compression for CSS and Javascript text files to boost the performance for assets served from a storage bucket it is necessary to upload the content in a GZIP format. The CDN doesn't support dynamically compressing content based on the browser request. The gsutil cp -Z flag enables automatic compression of files as they are copied to your bucket. When the file is copied it is stored in GZIP format and if the browser request includes accept encoding for GZIP then the bucket will serve the compressed content. This can also save you some storage costs. If the browser doesn't specify support for compression then the bucket will transcode the content back to plain text before sending the response.

Enabling cache control

The cache control best practices suggests to update the cache control for your assets.

Whether you are using the user interface or the API to upload your content you may find that you end up with a large number of files where you need to update the cache control. Doing this via the user interface can become tiresome for more than a couple of files.

If you are looking for a quick hack script that will update the cache control settings for every file in your bucket (* not intended for very large buckets) this script could be for you:

#!/usr/bin/bash BUCKET=<your bucket e.g. gs://some-bucket-name> files=$(gsutil ls -r $BUCKET); for i in $files; do if [[ "$i" == *: ]] || [[ "$i" == */ ]]; then echo "Skipping directory $i"; else   echo "Updating cache control for $i"; gsutil setmeta -h "cache-control:public, max-age=604800" $i; fi; done;
Note that I am setting the cache maximum age to 7 days in seconds. This will significantly improve cache performance of static content and can make use of edge caching.

Set up your ANAME record

For custom domain names you want to serve your content from which you configured above in the CDN resource setup you will now need to create ANAME records with your DNS provider. This step is really dependent upon your provider. Once your DNS has propagated you can now start to reconfigure your site to use the freshly created SSL resources.

Update: 2019 

If you aren't planning to use the default AppEngine SSL issuer then you should follow the custom SSL for App Engine guide. Note that you have to concatenate your certificate as:
cat my-private-key.cert ca-bundle.cert >> combined.cert


Top tips for refreshing Android skills with the Little Miracle prototype

Over the last few weeks I have been working on a prototype of a pregnancy contraction tracking app and wanted to share some tips from my experience so far.

Go native with Android

Android has a number of native solutions for problems you may experience during your development. One really good example of this is using java Threads vs TimerTask vs Handlers for updating the UI based on clock or timing events. In this case I was using the timer to schedule asynchronous events to update the user interface which is an anti pattern. When updating the user interface the best practice is to use Handler solutions. If you are seeing leaked context warnings or experiencing issues with thread scopes then there is probably a better way.

Compat[ibility] is main route

The compatibility libraries are not so much extras as the normal way to build things. When prototyping they can help hide a lot of the complexity of the ever evolving Android ecosystem. Unless you are developing for a specific device then the compatibility libraries are a must!


Changing teams at Google

After spending a little over a year working with Ads partners I am now moving to a different team working with Google partners! Part of the transition involves getting up to sped with Android development so I will be building a demo app over the next few weeks and wanted to share my experiences.

To make things more interesting I will be starting out with an older version of Android (Nougat) and migrating my app to new versions. At the same time I will migrate the app from Java to Kotlin.

In order to make things as real as possible I will be creating an app in a very competitive space (pregnancy tracking) and launching it on the app store. As I go I will share useful resources and guides that I tried to help me.

Hello World

To get started I will be taking a couple of courses to refresh my knowledge as it has been a year since I built an Android app and I am guessing a lot has changed. Here's where I started: