Introduction

On August 15, 2018, Google released the Alpha release of Google Cloud Run. Many of us saw the potential and went to work learning this new platform. Everything serverless gets our attention. Cloud Run is Google’s entry into serverless containers. On April 9, 2019, Cloud Run went into Beta and has lit on fire. To say that I am impressed is an understatement.

What is Google Cloud Run? Cloud Run is a managed compute platform for running stateless containers in the cloud. The only serious requirements are that your container must be invocable via HTTP requests and not require long running or background processes as they put the container to sleep in between HTTP requests. Cloud Run also makes deploying HTTPS and SSL certificates easy.

Key feature points:
  • Run HTTP apps and services
  • Simple developer experience
  • Fast auto-scaling
  • Scales to zero
  • Almost any language, any library, any runtime
  • HTTP and HTTPS
  • SSL certificates for your domain name
  • Integrated logging and monitoring – Stackdriver
  • Pay per use – no traffic equals no cost
  • Optional authentication

Cloud Run is a big brother to Cloud Functions. Both can do many of the same things. I prefer Cloud Run as I have control over the language, run-time libraries, and operating systems for my application. Just about anything that will run in a Docker container can be deployed to Cloud Run. Cloud Functions is still a favorite for small and tightly controlled microservices.

Cloud Run also supports Kubernetes, which I am not covering in this article. However, redeploying from Cloud Run to Cloud Run on GKE is as simple as adding one command line option. That is what I call elegant simplicity.

In this article, we will create a Python Flask web application and deploy it into a Docker container. Then we will take this container and deploy it to Cloud Run. Once we have everything working, we will create a domain name in our DNS server and deploy an SSL certificate.

This article covers development and deployment from a Windows 10 Professional desktop. Linux is similar but not covered in this article.

We will work with several products and services. Having a basic understanding will be helpful.

The final result will be a simple web application that responds at https://flask-python-example.jhanley.dev. Your endpoint will be different.

Assumptions:
  • You have gcloud installed and configured with the correct credentials and project
  • You have Docker installed
  • You have Python 3 installed

If you do not have Docker or do not want to install it, you can still follow the Google Cloud sections and build and run a container in Cloud Run. You just cannot build and run a local Docker container. You don’t even need Python installed.

Additional information

Google has several good videos to introduce you to Cloud Run. Here are several I like and their running time:

An often overlooked item is the size of your containers. You want them as small as possible to minimize container cold start times. This video is a nice introduction to this:

Do not forget container security. Make sure that your containers have the proper patches and have been scanned for vulnerabilities.

Getting Started

This article assumes that you have the CLI gcloud installed and configured with credentials. This article is CLI based and we will not be using the Google Cloud Console, except for Google Domains. Google’s GUI is excellent, but I prefer the CLI as I can create scripts, create better documentation, etc. Sometimes there are options that are not available in the GUI and you must use the CLI.

Install the Cloud SDK Beta and Alpha components:

Update the Cloud SDK:

Verify that the correct project is the default project:

If the correct project is not displayed, use this command to change the default project:

You can list the projects in your account. Some security configurations will not allow you to list projects. In that case, you will need to specify the default project manually as shown above.

Enable the Cloud Run Service

Set the default region for Cloud Run. This is obvious today, but soon there will be more regions announced:

For Cloud Run on GKE:

If you develop for BOTH Cloud Run and Cloud Run on GKE, you cannot set the properties as described above, because they will conflict. Instead, supply the –region parameter as needed in the gcloud command line for Cloud Run, and supply the –cluster and –cluster-location parameters as needed in the gcloud command line for Cloud Run on GKE.

Software Requirements

Download Git Repository

Update: May 16, 2019

I have published the files for this article on GitHub. https://github.com/jhanley-com/google-cloud-run-getting-started-python-flask

License: MIT License

Clone my repository to your system:

Develop the Python Flask Application

For this article, we will write a simple Python Flask application that displays “Hello Google Cloud Run World!” with a link to the Cloud Run website. We will write and test this from our Windows 10 desktop. The steps are similar for Linux and are not covered in this article.

For this application we just need Flask. Create the requirements.txt file with this content:

Install/verify that Flask is installed:

Let’s look at a simple Flask application. We will not be using this example, this is to simplify understanding Flask. This is a seven-line web server application! This example will listen on 127.0.0.1 port 5000:

We will use an expanded version. Create the application file app.py with this content:

Execute this code:

Click this link or open a web browser to http://localhost:8080/

You should see a page similar to this:

Press CTRL-C to kill the Flask web server.

I will not go into detail about Flask as there are extensive documentation and examples on the Internet. At this point, we have created a simple web server and ran it on our local desktop. I like to develop and test as much as possible locally as this is easier and faster than waiting for deployments to complete.

Develop the Docker Container

The next step is to take the website application and deploy it as a Docker container.

Create the Dockerfile file with this content:

Notice I have some lines commented out. The reason is that I like to start with a full container build (FROM python:3) and when deploying switch to a minimal build (FROM python:3-alpine). Sometimes I need to connect inside the container to debug, install tools, etc. Before deploying production code, build the smallest container you can. This will decrease costs, minimize the testing footprint, reduce data transfer time to start the container, and improve security.

Build the container:

You will receive a security warning from Docker on Windows:

This issue is handled in the Dockerfile with these lines:

The problem is that the Dockerfile COPY statements add execution permission to files. The chmod commands change the file permissions back to read-only. If you forget to do this, you will have Python execute errors.

Next, run the container and verify that everything works.

Click this link or open a web browser to http://localhost:8080/

You should see the same content again.

Press CTRL-C to kill the container.

Build the Container with Cloud Build

Everything we have done up to this point has not involved Google Cloud. Now we will switch and build our container in the cloud as the first step to deploy with Cloud Run.

Build the container using Cloud Build and store it in Cloud Container Registry. Replace my-project with your Google Cloud Project ID:

Once the build completes, you can list the container  images in Container Registry:

Deploy the Container to Cloud Run

Deploy the container from Container Registry to Cloud Run. Replace my-project with your Google Cloud Project ID:

When this command completes, you will see a message similar to:

Make a note of the endpoint in the message. Open a new browser and enter the URL.

Permission Denied

If the deploying identity (user or service account) is missing the permission run.services.setIamPolicy you must add the Cloud Run Admin IAM role to the identity. The role name is roles/run.admin. If that is not possible, remove the gcloud run deploy command line flag --allow-unauthenticated.

Create a Custom Domain and Certificate

If you are just creating an API, then making your Cloud Run instance easily accessible is not important. For websites, customers will expect a URL that is recognizable. I don’t like to click on weird URLs – you never know what is behind them. So, let’s go thru the process to create a custom domain and SSL certificate and make our website available as a subdomain.

Open a web browser and go to the Google Cloud Run console https://console.cloud.google.com/run. Click on Manage Custom Domains.

Click Add Mapping. Select the Cloud Run service we just deployed. Select your domain name. Enter your subdomain. In this example “flask-python-example”.

If your domain name does not appear, select “Verify a new domain …” and follow the prompts.

Click Continue. The next step is to create a CNAME in your DNS server with the information from this screen:

You will need to wait about ten to thirty minutes for Google to deploy the SSL certificate and for your DNS server to start responding to requests for the new domain name.

Open a web browser and go to your new domain. For this example: https://flask-python-example.jhanley.dev.

In a future article, I will cover HTTPS and SSL for Cloud Run including HTTPS redirection, secure headers, HSTS and some suggestions for Google to improve Cloud Run security.

More Information

Summary

Congratulations, you have deployed a simple containerized website to Google Cloud Run.

There are many more features of Google Cloud Run we have not covered in this introductory article. In future articles, I will cover more details including combining Cloud Run with other Google Cloud services for automation.

We can combine Cloud Run with other Google Cloud services, such as Cloud Storage and Pub/Sub to monitor the security settings on storage objects. This just scratches the surface of what we can do beyond just websites.

Credits

I write free articles about technology. Recently, I learned about Pexels.com which provides free images. The image in this article is courtesy of Pixabay at Pexels.

Date created: May 10, 2019
Last updated: June 3, 2019