After years of playing around with the various ways of running Docker in production, with varying success, it feels as though we now have a brilliant option in Google Container Engine.

This is a walkthrough on how to get Django up and running on Google Container Engine (GKE) using our sample starter project. It was written to accompany my talk at the London Django Meetup in March 2017. The slides from my talk are here.

This uses a demo container we've pushed to Docker Hub based on our Django starter project. The repo for our starter is at and our example image is at wildfish/django-starter-sample on DockerHub. For more info on using this with containers not based on our starter project have a look at the README in our kubernetes samples at

Sign Up For Google's Cloud Platform

If you don't already have an account, you'll need to sign up for Google's Cloud Platform. Do that here,

At time of writing, you get $300 of free usage credit, which will be plenty to cover this walkthrough and get you going.

Create a Project

Once you're logged in to the GKE console, from the project dropdown at the top of the screen select "Create Project".

Give your project a name, and make a note of the slug generated for it (in my case, "gkedemo-159611")

Install the CLI Tools

We need to install the Google Cloud command line tool, gcloud, and the Kubernetes CLI tool, kubectl for working with the service from the command line. gcloud is specific to Google's Cloud offering and works across their other cloud services whereas kubectl is for managing Kubernetes clusters in general, including those not running on GKE.

On Ubuntu or Debian:

export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl | sudo apt-key add -
sudo apt-get update && sudo apt-get install google-cloud-sdk kubectl

For others:

Authenticate and Set up CLI Tools

Authenticate with the service using oauth:

gcloud auth application-default login

We'll also set the defaults for the compute zone and project (from the previous step) which we want to work with. I'm using the europe-west1-d zone (in St. Ghislain, Belgium) which is closest to London but you may want to pick a different one. They're listed here.

gcloud config set project <your-project-slug>
gcloud config set compute/zone europe-west1-d

For some reason you need to visit the cluster list page in the UI before we can create a cluster so go here:

And now create our cluster. We're using the name gke-cluster but feel free to change to something more appropriate:

gcloud container clusters create gke-cluster

Now we tell the CLI tool that we want to use our new cluster:

gcloud container clusters get-credentials gke-cluster

And we're now set, with our command line tools pointing at our freshly created Kubernetes cluster ready for business.

Deploy our Project to the Cluster

The containers running on our cluster are stateless, so we need to create a persistent disk where we will keep our Postgres database files (note that this will change in the near future with Google Cloud SQL for Postgres). Create a 200gb disk named django-example-postgres-diskwith the following command:

gcloud compute disks create --size 200GB django-example-postgres-disk

Kubernetes objects are described in manifests using YAML (or JSON). Our example project includes manifests to create the services to run a Django project with a Postgres database and Redis cache.

If you haven't already, clone our example project, which includes the Kubernetes manifests for us to create these:

git clone

To create the objects in our cluster, we use kubectl create pointed at our directory of manifests. We can point the create command at a directory, so point it at the k8s dir from the cloned repository:

kubectl create -f k8s/

This kicks off the process of creating our objects on the cluster. Run the following to see the status of the pods, including the --watch switch to update the output as status changes.

kubectl get pod --watch

Wait until all of the pods are listed as running, and then we'll grab the external IP from the ingress:

kubectl get ing

Which will look something like this:

NAME      HOSTS     ADDRESS          PORTS     AGE
ingress   *   80        5m

Open a browser and hit the IP under the ADDRESS column and you should see the Django container up and running on GKE.

Having all of these services described in YAML manifests is really nice, as you can keep them version controlled with the rest of your code. If you ever make any changes you can apply updates using the apply command:

kubectl apply -f k8s/

You can also use a patch command to update just a part of a running deployment. For example, to change our running Django deployment to use a new version of our container with the label version-2 you'd use this command:

kubectl patch deployment django -p'{"spec":{"template":{"spec":{"containers":[{"name":"django","image":"wildfish/django-starter-sample:version-2"}]}}}}'

Note that you should use a new label for your docker image every build, so that Kubernetes knows that it's a new container.

What Next?

This is only intended as a starting point to cover the basics but it should be enough to get you up and running. We'd recommend creating your own registry in the Google Container Engine console and pushing your own containers there to use. In a later post we're hoping to cover using the recently announced Google Cloud Container Builder to provide examples for how to automate the building of your containers.

comments powered by Disqus


Pingbacks are open.