Deploy a CockroachDB Cloud Application with Google Cloud Run

On this page Carat arrow pointing down

This tutorial shows you how to use Google Cloud Run to deploy a containerized Django application that communicates with a CockroachDB Serverless cluster.

Prerequisites

Before starting the tutorial, do the following:

  1. Create a CockroachDB Cloud account.
  2. Create a Google Cloud account.
  3. Install the Google Cloud SDK.
  4. Install Docker Desktop.

Step 1. Create a CockroachDB Serverless cluster

  1. If you haven't already, sign up for a CockroachDB Cloud account.
  2. Log in to your CockroachDB Cloud account.
  3. On the Clusters page, click Create Cluster.
  4. On the Create your cluster page, select Serverless.

    Unless you change your monthly budget, this cluster will be free forever.

  5. Click Create cluster.

    Your cluster will be created in a few seconds and the Create SQL user dialog will display.

Step 2. Set up your cluster connection

Once your cluster is created, the Connect to cluster-name dialog displays. Use the information provided in the dialog to set up your cluster connection for the SQL user that was created by default:

  1. In your terminal, run the second command from the dialog to create a new certs directory on your local machine and download the CA certificate to that directory:

    icon/buttons/copy
    curl --create-dirs -o ~/.postgresql/root.crt -O https://cockroachlabs.cloud/clusters/<cluster-id>/cert
    

    Your cert file will be downloaded to ~/.postgresql/root.crt.

    icon/buttons/copy
    curl --create-dirs -o ~/.postgresql/root.crt -O https://cockroachlabs.cloud/clusters/<cluster-id>/cert
    

    Your cert file will be downloaded to ~/.postgresql/root.crt.

    icon/buttons/copy
    mkdir -p $env:appdata\.postgresql\; Invoke-WebRequest -Uri https://cockroachlabs.cloud/clusters/<cluster-id>/cert -OutFile $env:appdata\.postgresql\root.crt
    

    Your cert file will be downloaded to %APPDATA%/.postgresql/root.crt.

  2. Copy the connection string provided, which will be used in the next steps (and to connect to your cluster in the future).

    Warning:

    This connection string contains your password, which will be provided only once. If you forget your password, you can reset it by going to the SQL Users page.

    icon/buttons/copy
    cockroach sql --url 'postgresql://<username>:<password>@<serverless-host>:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt&options=--cluster=<routing-id>'
    

    icon/buttons/copy
    cockroach sql --url 'postgresql://<username>:<password>@<serverless-host>:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt&options=--cluster=<routing-id>'
    
    icon/buttons/copy
    cockroach sql --url "postgresql://<username>:<password>@<serverless-host>:26257/defaultdb?sslmode=verify-full&sslrootcert=$env:appdata/.postgresql/root.crt&options=--cluster=<routing-id>"
    

    Where:

    • <username> is the SQL user. By default, this is your CockroachDB Cloud account username.
    • <password> is the password for the SQL user. The password will be shown only once in the Connection info dialog after creating the cluster.
    • <serverless-host> is the hostname of the CockroachDB Serverless cluster.
    • <routing-id> identifies your tenant cluster on a multi-tenant host. For example, funny-skunk-123.
    • <cluster-id> is a unique string used to identify your cluster when downloading the CA certificate. For example, 12a3bcde-4fa5-6789-1234-56bc7890d123.

    You can find these settings in the Connection parameters tab of the Connection info dialog.

Step 3. Create a database

  1. If you haven't already, download the CockroachDB binary.
  2. Start the built-in SQL shell using the connection string you got from the CockroachDB Cloud Console earlier:

    icon/buttons/copy
    $ cockroach sql \
    --url='postgres://<username>:<password>@<global host>:26257/<cluster_name>.defaultdb?sslmode=verify-full&sslrootcert=<certs_dir>/cc-ca.crt'
    

    In the connection string copied from the CockroachDB Cloud Console, your username, password and cluster name are pre-populated. Replace the <certs_dir> placeholder with the path to the certs directory that you created earlier.

  3. In the SQL shell, create the bank database that your application will use:

    icon/buttons/copy
    > CREATE DATABASE bank;
    
  4. Exit the SQL shell:

    icon/buttons/copy
    > \q
    

Step 4. Get the application code

  1. Clone the code's GitHub repo:

    icon/buttons/copy
    $ git clone https://github.com/cockroachlabs/example-app-python-django/
    
  2. Create a new folder named certs at the top level of the example-app-python-django project, and then copy the root certificate that you downloaded for your cluster to the new folder.

    The project directory structure should look like this:

    ├── Dockerfile
    ├── README.md
    ├── certs
    │   └── root.crt
    ├── cockroach_example
    │   ├── cockroach_example
    │   │   ├── __init__.py
    │   │   ├── asgi.py
    │   │   ├── migrations
    │   │   │   ├── 0001_initial.py
    │   │   │   └── __init__.py
    │   │   ├── models.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   ├── views.py
    │   │   └── wsgi.py
    │   └── manage.py
    └── requirements.txt
    

Step 5. Initialize the database and test the app locally

  1. At the top level of the app's project directory, create and then activate a virtual environment:

    icon/buttons/copy
    $ virtualenv env
    
    icon/buttons/copy
    $ source env/bin/activate
    
  2. Install the required modules to the virtual environment:

    icon/buttons/copy
    $ pip install -r requirements.txt
    
  3. Set the DATABASE_URL environment variable to the connection string provided in the Connection info window of the CockroachDB Cloud Console, but with the root certificate located in the local certs directory:

    icon/buttons/copy
    $ export DATABASE_URL="postgresql://user:password@free-tier.gcp-us-central1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=certs/root.crt&options=--cluster%3Drouting-id"
    

    This Django app uses the dj_database_url module to configure the database connection from a connection URL. The module uses the value assigned to the DATABASE_URL environment variable for the connection.

    Note:

    In the Cloud Run deployment, we use the Google Cloud Secret Manager to define the DATABASE_URL environment variable for the deployment.

  4. Execute the initial database schema migration:

    icon/buttons/copy
    $ python3 cockroach_example/manage.py migrate
    

    This migration initializes the bank database with the tables defined in models.py, in addition to some other tables for the admin functionality included with Django's starter application.

  5. Run the app:

    icon/buttons/copy
    $ python3 cockroach_example/manage.py runserver 0.0.0.0:8000
    

    The output should look like this:

    ...
    Starting development server at http://0.0.0.0:8000/
    Quit the server with CONTROL-C.
    

    To perform simple reads and writes to the database, you can send HTTP requests to the application at http://0.0.0.0:8000/.

  6. In a new terminal, use curl to send a POST request to the application:

    icon/buttons/copy
    $ curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"name":"Carl"}' http://0.0.0.0:8000/customer/
    

    This request inserts a new row into the cockroach_example_customers table.

  7. Send a GET request to read from the cockroach_example_customers table:

    icon/buttons/copy
    $ curl http://0.0.0.0:8000/customer/
    
    [{"id": "bb7d6c4d-efb3-45f8-b790-9911aae7d8b2", "name": "Carl"}]
    

    You can also query the table directly in the SQL shell to see the changes:

    icon/buttons/copy
    > SELECT * FROM bank.cockroach_example_customers;
    
                       id                  | name
    ---------------------------------------+-------
      bb7d6c4d-efb3-45f8-b790-9911aae7d8b2 | Carl
    (1 row)
    
  8. Enter Ctrl+C to stop the application.

Step 6. Configure GCP

  1. In the terminal, authenticate the gcloud command-line tool with your Google Cloud account:

    Note:

    gcloud is included with the Google Cloud SDK installation.

    icon/buttons/copy
    $ gcloud auth login
    

    Follow the prompts to authenticate.

  2. Create a Google Cloud project for the application deployment:

    icon/buttons/copy
    $ gcloud projects create <gcp_project_id>
    
    Note:

    You can specify a location for the project within your Google Cloud resources with the --organization or --folder flags.

  3. Configure the CLI to use your Google Cloud account and the new project ID by default:

    icon/buttons/copy
    $ gcloud init
    
  4. Set the PROJECT_ID environment variable:

    icon/buttons/copy
    $ export PROJECT_ID=<gcp_project_id>
    

    For the rest of the tutorial, we use PROJECT_ID to refer to the project ID.

Step 7. Containerize the application and push it to the registry

  1. Build the Docker image locally:

    icon/buttons/copy
    $ docker build -t gcr.io/$PROJECT_ID/crdb-sample:v1 .
    

    If there are no errors, the container built successfully.

  2. Authenticate Docker with GCP's Container Registry:

    icon/buttons/copy
    $ gcloud auth configure-docker
    
  3. Enable the Container Registry API for the project:

    icon/buttons/copy
    $ gcloud services enable containerregistry.googleapis.com
    
  4. Push the Docker image to the project's registry.

    icon/buttons/copy
    $ docker push gcr.io/$PROJECT_ID/crdb-sample:v1
    

Step 8. Create a secret for the database connection URI

  1. Create a service account to manage the secrets for your project:

    icon/buttons/copy
    $ gcloud iam service-accounts create cockroach-labs
    
  2. Enable the Secret Manager API for the project:

    icon/buttons/copy
    $ gcloud services enable secretmanager.googleapis.com
    
  3. Create a secret for the connection string stored locally in the DATABASE_URL environment variable, and bind the new service account to the secret.

    icon/buttons/copy
    $ echo $DATABASE_URL | gcloud secrets create cockroach-connection-uri --data-file=- --replication-policy=automatic
    
    icon/buttons/copy
    $ gcloud secrets add-iam-policy-binding cockroach-connection-uri \
        --member=serviceAccount:cockroach-labs@${PROJECT_ID}.iam.gserviceaccount.com \
        --role=roles/secretmanager.secretAccessor
    

Step 9. Deploy the application on Cloud Run

  1. Enable the Cloud Run API for the project:

    icon/buttons/copy
    $ gcloud services enable run.googleapis.com
    
  2. Create a Cloud Run service for the application:

    icon/buttons/copy
    $ gcloud alpha run deploy crl-app --region us-central1 --allow-unauthenticated \
     --service-account=cockroach-labs@${PROJECT_ID}.iam.gserviceaccount.com \
       --set-secrets="DATABASE_URL=cockroach-connection-uri:latest" \
       --image=gcr.io/${PROJECT_ID}/crdb-sample:v1
    

    Note the following:

    • The --region flag specifies the region of the CockroachDB node targeted in the connection string.
    • The --service-account flag specifies the cockroach-labs service account that you created earlier for the app deployment.
    • The --set-secrets flag sets the DATABASE_URL environment variable to the cockroach-connection-uri secret that you created earlier.
    • The --image flag specifies the container image URL for the crdb-sample image that you pushed to the container registry.

    If prompted, select Cloud Run (fully managed).

After the revision is deployed, you should be able to send requests to the application from a browser, or using a REST client (e.g., curl). For example:

icon/buttons/copy
$ curl https://<GCR_HOST>/customer/
[{"id": "bb7d6c4d-efb3-45f8-b790-9911aae7d8b2", "name": "Carl"}]
Warning:

By default, the sample application allows all hosts/domain names to serve the application.

After testing, we recommend that you update the ALLOWED_HOSTS property in settings.py to allow only a local testing URL and the Cloud Run service URL to serve the application.

See also

You might also be interested in the following pages:


Yes No
On this page

Yes No