> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a CockroachDB Cloud Application with Google Cloud Run

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

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

## Before you begin

Before starting the tutorial, do the following:

1. Create a [Google Cloud](https://cloud.google.com/) account and log in.
2. Install the [Google Cloud SDK](https://cloud.google.com/sdk).
3. Install [Docker Desktop](https://www.docker.com/products/docker-desktop).

## Step 1. Create a CockroachDB Standard cluster

1. <InternalLink version="cockroachcloud" path="create-an-account">Create a CockroachDB Cloud account</InternalLink>. If this is your first CockroachDB Cloud organization, it will be credited with \$400 in <InternalLink version="cockroachcloud" path="free-trial">free trial credits</InternalLink> to get you started.

2. On the **Get Started** page, click **Create cluster**.

3. On the **Select a plan** page, select **Standard**.

4. On the **Cloud & Regions** page, select a cloud provider (GCP or AWS).

5. In the **Regions** section, select a region for the cluster. Refer to <InternalLink version="cockroachcloud" path="regions">CockroachDB Cloud Regions</InternalLink> for the regions where CockroachDB Standard clusters can be deployed. To create a multi-region cluster, click **Add region** and select additional regions.

6. Click **Next: Capacity**.

7. On the **Capacity** page, keep the <InternalLink version="cockroachcloud" path="plan-your-cluster">**Provisioned capacity**</InternalLink> at the default value of 2 vCPUs.

   Click **Next: Finalize**.

8. On the **Finalize** page, name your cluster. If an active free trial is listed in the right pane, you will not need to add a payment method, though you will need to do this by the <InternalLink version="cockroachcloud" path="free-trial#add-payment-methods">end of the trial</InternalLink> to maintain your organization's clusters.

   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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`.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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`.

   ```powershell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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).

<Danger>
  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 for the cluster, found at `https://cockroachlabs.cloud/cluster/<CLUSTER ID>/users`.
</Danger>

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
cockroach sql --url 'postgresql://<username:<password@<cluster-host:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt'
```

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
cockroach sql --url 'postgresql://<username:<password@<cluster-host:26257/defaultdb?sslmode=verify-full&sslrootcert='$HOME'/.postgresql/root.crt'
```

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
cockroach sql --url "postgresql://<username:<password@<cluster-host:26257/defaultdb?sslmode=verify-full&sslrootcert=$env:appdata/.postgresql/root.crt"
```

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.
* `<cluster-hostname` is the hostname of your CockroachDB Cloud cluster.
* `<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, <InternalLink path="install-cockroachdb">download the CockroachDB SQL Shell binary</InternalLink>.

2. Start the <InternalLink path="cockroach-sql">built-in SQL shell</InternalLink> using the connection string you got from the CockroachDB Cloud Console earlier:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   cockroach sql \
   --url='postgres://<username:<password@<global host:26257/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 <code>{'{certs_dir}'}</code> 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:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   > CREATE DATABASE bank;
   ```

4. Exit the SQL shell:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   > \q
   ```

## Step 4. Get the application code

1. Clone the example code's GitHub repo:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   git clone https://github.com/cockroachlabs/example-app-python-django/
   ```

2. Create a new directory 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 directory.

   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   virtualenv env
   ```

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   source env/bin/activate
   ```

2. Install the required modules to the virtual environment:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   export DATABASE_URL="postgresql://$USER:$PASSWORD@random-cluster-name-4300.6wr.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=root.crt"
   ```

   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.
</Note>

1. Execute the initial database schema migration:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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.

2. Run the app:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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/](http://0.0.0.0:8000/).

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

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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.

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

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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 <InternalLink path="cockroach-sql">SQL shell</InternalLink> to see the changes:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   > SELECT * FROM bank.cockroach_example_customers;
   ```

   ```
                      id                  | name
   ---------------------------------------+-------
     bb7d6c4d-efb3-45f8-b790-9911aae7d8b2 | Carl
   (1 row)
   ```

5. 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](https://cloud.google.com/sdk) installation.
</Note>

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
gcloud auth login
```

Follow the prompts to authenticate.

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

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud projects create {gcp_project_id}
   ```

<Note>
  You can specify a location for the project within your Google Cloud resources by using the `--organization` or `--folder` flags.
</Note>

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

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud init
   ```

2. Set the `PROJECT_ID` environment variable:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud auth configure-docker
   ```

3. Enable the Container Registry API for the project:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud services enable containerregistry.googleapis.com
   ```

4. Push the Docker image to the project's registry.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud iam service-accounts create cockroach-labs
   ```

2. Enable the Secret Manager API for the project:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   echo $DATABASE_URL | gcloud secrets create cockroach-connection-uri --data-file=- --replication-policy=automatic
   ```

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   gcloud services enable run.googleapis.com
   ```

2. Create a [Cloud Run](https://console.cloud.google.com/run/) service for the application:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   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)`.

3. After the revision is deployed, verify that you can send requests to the application from a browser or a REST client:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   curl https://<GCR_HOST>/customer/
   ```

   ```
   [{"id": "bb7d6c4d-efb3-45f8-b790-9911aae7d8b2", "name": "Carl"}]
   ```

4. 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`](https://docs.djangoproject.com/en/3.2/ref/settings/#allowed-hosts) to allow only a local testing URL and the Cloud Run service URL to serve the application.

## See also

* <InternalLink path="build-a-python-app-with-cockroachdb-django">Build a Simple Django App with CockroachDB</InternalLink>
* <InternalLink path="movr-flask-deployment">Deploy a Global Serverless Application</InternalLink>

You might also be interested in the following pages:

* <InternalLink path="connection-parameters">Client Connection Parameters</InternalLink>
* <InternalLink path="connection-pooling">Connection Pooling</InternalLink>
* <InternalLink path="demo-replication-and-rebalancing">Data Replication</InternalLink>
* <InternalLink path="demo-cockroachdb-resilience">CockroachDB Resilience</InternalLink>
* <InternalLink path="demo-replication-and-rebalancing">Replication & Rebalancing</InternalLink>
* <InternalLink path="demo-automatic-cloud-migration">Cross-Cloud Migration</InternalLink>
* <InternalLink path="orchestrate-a-local-cluster-with-kubernetes-insecure">Automated Operations</InternalLink>
