Cloud Run is a managed compute platform that enables you to run stateless containers that are invocable via HTTP requests. Cloud Run is serverless: it abstracts away all infrastructure management, so you can focus on what matters most — building great applications.

It is built from Knative, letting you choose to run your containers either fully managed with Cloud Run, or in your Google Kubernetes Engine cluster with Cloud Run on GKE.

The goal of this codelab is for you to build a container image and deploying it to Cloud Run.

Codelab-at-a-conference setup

If you see a "request account button" at the top of the main Codelabs window, click it to obtain a temporary account. Otherwise ask one of the staff for a coupon with username/password.

These temporary accounts have existing projects that are set up with billing so that there are no costs associated for you with running this codelab.

Note that all these accounts will be disabled soon after the codelab is over.

Use these credentials to log into the machine or to open a new Google Cloud Console window https://console.cloud.google.com/. Accept the new account Terms of Service and any updates to Terms of Service.

Here's what you should see once logged in:

When presented with this console landing page, please select the only project available. Alternatively, from the console home page, click on "Select a Project" :

Google Cloud Shell

While Google Cloud can be operated remotely from your laptop, in this codelab we will be using Google Cloud Shell, a command line environment running in the Cloud.

This Debian-based virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on the Google Cloud, greatly enhancing network performance and authentication. This means that all you will need for this codelab is a browser (yes, it works on a Chromebook).

To activate Google Cloud Shell, from the developer console simply click the button on the top right-hand side (it should only take a few moments to provision and connect to the environment):

activateCloudShell.png

Click the "Start Cloud Shell" button:

Screen Shot 2017-06-14 at 10.13.43 PM.png

Once connected to the cloud shell, you should see that you are already authenticated and that the project is already set to your PROJECT_ID :

gcloud auth list

Command output

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Command output

[core]
project = <PROJECT_ID>

Cloud Shell also sets some environment variables by default which may be useful as you run future commands.

echo $GOOGLE_CLOUD_PROJECT

Command output

<PROJECT_ID>

If for some reason the project is not set, simply issue the following command :

gcloud config set project <PROJECT_ID>

Looking for your PROJECT_ID? Check out what ID you used in the setup steps or look it up in the console dashboard:

Project_ID.png

IMPORTANT: Finally, set the default zone and project configuration:

gcloud config set compute/zone us-central1-f

You can choose a variety of different zones. Learn more in the Regions & Zones documentation.

Enable the Cloud Run API

From Cloud Shell, enable the Cloud Build and Cloud Run APIs:

gcloud services enable cloudbuild.googleapis.com run.googleapis.com

This should produce a successful message similar to this one:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

We'll build a simple Flask-based Python application responding to HTTP requests.

To build your application, use Cloud Shell to create a new directory named helloworld-python and change directory into it:

mkdir ~/helloworld-python
cd ~/helloworld-python

Using one of your preferred command line editors (nano, vim, or emacs) or the Cloud Shell web editor (click on the "Launch code editor" pen-shaped icon), create a file named app.py and paste the following code into it:

app.py

from flask import Flask, request

app = Flask(__name__)


@app.route('/', methods=['GET'])
def hello():
    """Return a friendly HTTP greeting."""
    who = request.args.get('who', 'World')
    return f'Hello {who}!\n'


if __name__ == '__main__':
    # Used when running locally only. When deploying to Cloud Run,
    # a webserver process such as Gunicorn will serve the app.
    app.run(host='localhost', port=8080, debug=True)

This code creates a basic web server responding to HTTP GET requests with a friendly message. Your app is now ready to be containerized, tested, and uploaded to Container Registry.

To containerize the sample app, create a new file named Dockerfile in the same directory as the source files, and copy the following content:

Dockerfile

# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.7-slim

# Install production dependencies.
RUN pip install Flask gunicorn

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 app:app

Define the PROJECT_ID and DOCKER_IMG environment variables which will be used throughout the next steps and make sure they have the correct values:

PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID

DOCKER_IMG="gcr.io/$PROJECT_ID/helloworld-python"
echo $DOCKER_IMG

Now, build your container image using Cloud Build, by running the following command from the directory containing the Dockerfile:

gcloud builds submit --tag $DOCKER_IMG

Once pushed to the registry, you will see a SUCCESS message containing the image name. The image is stored in Container Registry and can be re-used if desired.

You can list all the container images associated with your current project using this command:

gcloud container images list

Before deploying, run and test the application locally from Cloud Shell, you can start it using these standard docker commands:

docker pull $DOCKER_IMG
docker run -p 8080:8080 $DOCKER_IMG

In the Cloud Shell window, click on the "Web preview" icon and select "Preview on port 8080":

This should open a browser window showing the "Hello World!" message. You can also simply use curl localhost:8080 from another Cloud Shell session. When you're done, you can stop your docker run command with Ctrl+c.

Deploying your containerized application to Cloud Run is done using the following command:

gcloud run deploy --image $DOCKER_IMG --platform managed

When prompted:

Then wait a few moments until the deployment is complete. On success, the command line displays the service URL:

Service [helloworld-python] revision [helloworld-python-...] has been deployed
and is serving traffic at https://helloworld-python-ouu74wujkq-uc.a.run.app

You can now visit your deployed container by opening the service URL in a web browser:

Congratulations! You have just deployed an application packaged in a container image to Cloud Run. Cloud Run automatically and horizontally scales your container image to handle the received requests, then scales down when demand decreases. You only pay for the CPU, memory, and networking consumed during request handling.