Deploy a Multi-Region Web Application

On this page Carat arrow pointing down

This page walks you through deploying an application and database in multiple regions. It is the fifth and final section of the Develop and Deploy a Multi-Region Web Application tutorial.

Note:

CockroachDB versions v21.1 and above support new multi-region capabilities, with different SQL syntax.

For the latest version of the application and database schema built on v21.1 multi-region features, see the movr-flask repository.

For the latest version of the tutorial, see the v21.1 docs.

Before you begin

Before you begin this section, complete the previous section of the tutorial, Develop a Multi-Region Web Application. After you finish developing and debugging your multi-region application in a local development environment, you are ready to deploy the application and database in multiple regions.

In addition to the requirements listed in Setting Up a Virtual Environment for Developing Multi-Region Applications, make sure that you have the following installed on your local machine:

Multi-region database deployment

In production, you want to start a secure CockroachDB cluster, with nodes on machines located in different areas of the world. To deploy CockroachDB in multiple regions, using CockroachDB Serverless:

  1. Create a CockroachDB Cloud account at https://cockroachlabs.cloud.

  2. Request a multi-region CockroachDB Cloud cluster on GCP, in regions us-west1, us-east1, and europe-west1.

  3. After the cluster is created, open the console, and select the cluster.

  4. Select SQL Users from the side panel, select Add user, give the user a name and a password, and then add the user. You can use any user name except "root".

  5. Select Networking from the side panel, and then select Add network. Give the network any name you'd like, select either a New network or a Public network, check both UI and SQL, and then add the network. In this example, we use a public network.

  6. Select Connect at the top-right corner of the cluster console.

  7. Select the User that you created, and then Continue.

  8. Copy the connection string, with the user and password specified.

  9. Go back, and retrieve the connection strings for the other two regions.

  10. Download the cluster cert to your local machine (it's the same for all regions).

  11. Open a new terminal, and run the dbinit.sql file on the running cluster to initialize the database. You can connect to the database from any node on the cluster for this step.

    icon/buttons/copy
    $ cockroach sql --url any-connection-string < dbinit.sql
    
    Note:

    You need to specify the password in the connection string!

    e.g.,

    $ cockroach sql --url \ 'postgresql://user:password@region.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=certs-dir/movr-app-ca.crt' < dbinit.sql
    
Note:

You can also deploy CockroachDB manually. For instructions, see the Manual Deployment page of the Cockroach Labs documentation site.

Multi-region application deployment (GKE)

To deploy an application in multiple regions in production, we recommend that you use a managed Kubernetes engine, like Amazon EKS, Google Kubernetes Engine, or Azure Kubernetes Service. To route requests to the container cluster deployed closest to clients, you should also set up a multi-cluster ingress.

In this tutorial, we use kubemci to configure a GCP HTTP Load Balancer to container clusters deployed on GKE.

Note:

To serve a secure web application, you also need a public domain name!

  1. If you do not have a gcloud account, create one at https://cloud.google.com/.

  2. Create a gcloud project on the GCP console.

  3. Optional: Enable the Google Maps Embed API, create an API key, restrict the API key to all subdomains of your domain name (e.g., https://site.com/*), and retrieve the API key.

    Note:

    The example HTML templates include maps. Not providing an API key to the application will not break the application.

  4. Configure/authorize the gcloud CLI to use your project and region.

    icon/buttons/copy
    $ gcloud init
    
    icon/buttons/copy
    $ gcloud auth login
    
    icon/buttons/copy
    $ gcloud auth application-default login
    
  5. If you haven't already, install kubectl.

    icon/buttons/copy
    $ gcloud components install kubectl
    
  6. Build and run the Docker image locally.

    icon/buttons/copy
    $ docker build -t gcr.io/<gcp_project>/movr-app:v1 .
    

    If there are no errors, the container built successfully.

  7. Push the Docker image to the project’s gcloud container registry.

    icon/buttons/copy
    $ docker push gcr.io/<gcp_project>/movr-app:v1
    
  8. Create a K8s cluster for all three regions.

    icon/buttons/copy
    $ gcloud config set compute/zone us-east1-b && \
      gcloud container clusters create movr-us-east
    
    icon/buttons/copy
    $ gcloud config set compute/zone us-west1-b && \
      gcloud container clusters create movr-us-west
    
    icon/buttons/copy
    $ gcloud config set compute/zone europe-west1-b && \
      gcloud container clusters create movr-europe-west
    
  9. Add the container credentials to kubeconfig.

    icon/buttons/copy
    $ KUBECONFIG=~/mcikubeconfig gcloud container clusters get-credentials --zone=us-east1-b movr-us-east
    
    icon/buttons/copy
    $ KUBECONFIG=~/mcikubeconfig gcloud container clusters get-credentials --zone=us-west1-b movr-us-west
    
    icon/buttons/copy
    $ KUBECONFIG=~/mcikubeconfig gcloud container clusters get-credentials --zone=europe-west1-b movr-europe-west
    
  10. For each cluster context, create a secret for the connection string, Google Maps API, and the certs, and then create the k8s deployment and service using the movr.yaml manifest file:

    icon/buttons/copy
    $ kubectl config use-context <context-name> && \
    kubectl create secret generic movr-db-cert --from-file=cert=<full-path-to-cert> && \
    kubectl create secret generic movr-db-uri --from-literal=DB_URI="connection-string" && \
    kubectl create secret generic maps-api-key --from-literal=API_KEY="APIkey" \
    kubectl create -f ~/movr-flask/movr.yaml
    

    Where:

    • <context-name> is the cluster context for a regional deployment. To get the contexts for all deployments, run $ kubectl config get-contexts -o name.
    • <full-path-to-cert> is the full directory path to the certificates for the multi-region CockroachDB Cloud cluster. These certificates are available for download from the CockroachDB Cloud console, and they are the same for all regions.
    • <connection-string> is the full connection string to the gateway node of a regional CockroachDB Cloud deployment. It should look something like:
      postgresql://user:password@region.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=certs-dir/movr-app-ca.crt
    • <APIkey> is the API key for the Google Maps Embed API. This API key is not required to run the demo application. Not providing a Google Maps Embed API key will not break the application.

    Note:

    Secrets must be generated for each cluster context.

  11. Reserve a static IP address for the ingress.

    icon/buttons/copy
    $ gcloud compute addresses create --global movr-ip
    

    To verify that you successfully created the new IP address, run the following command:

    icon/buttons/copy
    $ gcloud compute addresses list
    
  12. Download kubemci, and then make it executable:

    icon/buttons/copy
    $ chmod +x ~/kubemci
    
  13. Use kubemci to make the ingress.

    icon/buttons/copy
    $ ~/kubemci create movr-mci \
    --ingress=<path>/movr-flask/mcingress.yaml \
    --gcp-project=<gcp_project> \
    --kubeconfig=<path>/mcikubeconfig
    
    Note:

    kubemci requires full paths.

  14. In GCP's Load balancing console (found under Network Services), select and edit the load balancer that you just created.

    1. Edit the backend configuration.
      • Expand the advanced configurations, and add a custom header: X-City: {client_city}. This forwards an additional header to the application telling it what city the client is in. The header name (X-City) is hardcoded into the example application.
    2. Edit the frontend configuration, and add a new frontend.
      • Under "Protocol", select HTTPS.
      • Under "IP address", select the static IP address that you reserved earlier (e.g., "movr-ip").
      • Under "Certificate", select "Create a new certificate".
      • On the "Create a new certificate" page, give a name to the certificate (e.g., "movr-ssl-cert"), check "Create Google-managed certificate", and then under "Domains", enter a domain name that you own and want to use for your application.
    3. Review and finalize the load balancer, and then "Update".

      Note:

      It will take several minutes to provision the SSL certificate that you just created for the frontend.

  15. Check the status of the ingress.

    icon/buttons/copy
    $ ~/kubemci list --gcp-project=<gcp_project>
    
  16. In the Cloud DNS console (found under Network Services), create a new zone. You can name the zone whatever you want. Enter the same domain name for which you created a certificate earlier.

  17. Select your zone, and copy the nameserver addresses (under "Data") for the recordset labeled "NS".

  18. Outside of the GCP console, through your domain name provider, add the nameserver addresses to the authoritative nameserver list for your domain name.

    Note:

    It can take up to 48 hours for changes to the authoritative nameserver list to take effect.

  19. Navigate to the domain name and test out your application.

Next steps

Develop your own application

This tutorial demonstrates how to develop and deploy an example multi-region application. Most of the development instructions are specific to Python, Flask, and SQLAlchemy, and most of the deployment instructions are specific to Google Cloud Platform, Docker, and Kubernetes. CockroachDB supports many more drivers and ORM's for development. You can deploy applications using a number of cloud provider orchestration tools and networking services. We encourage you to modify the code and deployments to fit your framework and use case.

Upgrade your deployment

Some time after you have deployed your application, you will likely need to push changes that you've made locally. When pushing changes, be aware that you defined the database separate from the application. If you change a data type, for example, in your application, you will also need to modify the database schema to be compatible with your application's requests. For information about making online changes to database schemas, see Online Schema Changes.

See also


Yes No
On this page

Yes No