Migre apps Node.js do Heroku para o Cloud Run


Este tutorial descreve como migrar apps Web Node.js que estão a ser executadas no Heroku para o Cloud Run no Google Cloud. Este tutorial destina-se a arquitetos e proprietários de produtos que querem migrar as respetivas apps do Heroku para serviços geridos no Google Cloud.

O Cloud Run é uma plataforma de computação gerida que lhe permite executar contentores sem estado invocáveis através de pedidos HTTP. É criada com base no código aberto Knative, o que permite a portabilidade entre plataformas e suporta fluxos de trabalho de contentores e normas para a entrega contínua. A plataforma Cloud Run está bem integrada com o conjunto de produtos e facilita a conceção e o desenvolvimento de apps portáteis, escaláveis e resilientes. Google Cloud

Neste tutorial, vai aprender a migrar uma app Google Cloud escrita em Node.js e que usa o Heroku Postgres como um serviço de apoio no Heroku. A app Web está contentorizada e alojada no Cloud Run e usa o Cloud SQL para PostgreSQL como camada de persistência.

No tutorial, usa uma app simples denominada Tasks que lhe permite ver e criar tarefas. Estas tarefas são armazenadas no Heroku Postgres na implementação atual da app no Heroku.

Este tutorial pressupõe que conhece a funcionalidade básica do Heroku e que tem uma conta do Heroku (ou acesso a uma). Também pressupõe que tem conhecimentos sobre o Cloud Run, o Cloud SQL, o Docker e o Node.js.

Objetivos

  • Crie uma imagem Docker para implementar a app no Cloud Run.
  • Crie uma instância do Cloud SQL para PostgreSQL para servir como back-end após a migração para o Google Cloud.
  • Reveja o código Node.js para compreender como o Cloud Run se liga ao Cloud SQL e para ver as alterações ao código (se existirem) necessárias para migrar do Heroku para o Cloud Run.
  • Migre dados do Heroku Postgres para o Cloud SQL para PostgreSQL.
  • Implemente a app no Cloud Run.
  • Teste a app implementada.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Também lhe pode ser cobrado o uso de recursos no Heroku.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Cloud SQL, Cloud Build, Cloud Run, Container Registry, Service Networking, Serverless VPC Access APIs.

    Enable the APIs

  5. Make sure that you have the following role or roles on the project: Cloud Run > Cloud Run Admin, Cloud Storage > Storage Admin, Cloud SQL > Cloud SQL Admin, Compute Engine > Compute Network Admin, Resource Manager > Project IAM Admin, Cloud Build > Cloud Build Editor, Serverless VPC Access > Serverless VPC Access Admin, Logging > Logs Viewer, Service Accounts > Service Account Admin, Service Accounts > Service Account User, and Service Usage > Service Usage Consumer

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Aceder ao IAM
    2. Selecione o projeto.
    3. Clique em Conceder acesso.
    4. No campo Novos responsáveis, introduza o identificador do utilizador. Normalmente, este é o endereço de email de uma Conta Google.

    5. Na lista Selecionar uma função, selecione uma função.
    6. Para conceder funções adicionais, clique em Adicionar outra função e adicione cada função adicional.
    7. Clique em Guardar.
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Verify that billing is enabled for your Google Cloud project.

  8. Enable the Cloud SQL, Cloud Build, Cloud Run, Container Registry, Service Networking, Serverless VPC Access APIs.

    Enable the APIs

  9. Make sure that you have the following role or roles on the project: Cloud Run > Cloud Run Admin, Cloud Storage > Storage Admin, Cloud SQL > Cloud SQL Admin, Compute Engine > Compute Network Admin, Resource Manager > Project IAM Admin, Cloud Build > Cloud Build Editor, Serverless VPC Access > Serverless VPC Access Admin, Logging > Logs Viewer, Service Accounts > Service Account Admin, Service Accounts > Service Account User, and Service Usage > Service Usage Consumer

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Aceder ao IAM
    2. Selecione o projeto.
    3. Clique em Conceder acesso.
    4. No campo Novos responsáveis, introduza o identificador do utilizador. Normalmente, este é o endereço de email de uma Conta Google.

    5. Na lista Selecionar uma função, selecione uma função.
    6. Para conceder funções adicionais, clique em Adicionar outra função e adicione cada função adicional.
    7. Clique em Guardar.
  10. Configurar o seu ambiente

    1. Abra o Cloud Shell.

      ABRIR Cloud Shell

    2. No Cloud Shell, defina as variáveis de ambiente e os valores predefinidos para a CLI do Google Cloud usada neste tutorial.

      gcloud config set project PROJECT_ID
      gcloud config set run/region us-central1
      

      Substitua PROJECT_ID pelo ID do seu projeto.

    Arquitetura

    As figuras seguintes descrevem a arquitetura da app Web no Heroku (tal como está) e o esquema arquitetónico no Google Cloud (que vai criar).

    Arquitetura tal como está no Heroku.
    Figura 1. Arquitetura tal como está no Heroku

    A app Tasks implementada atualmente no Heroku consiste em um ou mais web dynos. Os dynos Web podem receber e responder ao tráfego HTTP, ao contrário dos dynos de trabalho, que são mais adequados para tarefas em segundo plano e tarefas programadas. A app apresenta uma página de índice que apresenta tarefas armazenadas numa base de dados Postgres, usando a biblioteca de modelos Mustache para Node.js.

    Pode aceder à app através de um URL HTTPS. Uma rota /tasks nesse URL permite-lhe criar novas tarefas.

    Arquitetura tal como está no Heroku.
    Figura 2. Arquitetura na qual cria Google Cloud

    No Google Cloud, o Cloud Run é usado como a plataforma sem servidor para implementar a app Tasks. O Cloud Run foi concebido para executar contentores sem estado e baseados em pedidos. É adequado quando precisa que o seu serviço gerido suporte apps contentorizadas com escala automática e também escala para zero quando não estão a publicar tráfego.

    Mapeamento de componentes usados no Heroku para o Google Cloud

    A tabela seguinte mapeia os componentes na plataforma Heroku para Google Cloud. Este mapeamento ajuda a traduzir a arquitetura descrita neste tutorial do Heroku para o Google Cloud.

    Componente Plataforma Heroku Google Cloud
    Contentores Dynos: O Heroku usa o modelo de contentor para criar e dimensionar apps Heroku. Estes contentores Linux são denominados dynos e podem ser dimensionados para um número que especificar para suportar as exigências de recursos da sua app Heroku. Pode selecionar entre uma variedade de tipos de dynos com base nos requisitos de memória e CPU da sua app. Contentores do Cloud Run: Google Cloud suporta a execução de cargas de trabalho em contentores sem estado que podem ser executados num ambiente totalmente gerido ou em clusters do Google Kubernetes Engine (GKE).
    App Web App Heroku: os dynos são os elementos básicos das apps Heroku. Normalmente, as apps consistem num ou mais tipos de dynos, geralmente uma combinação de dynos web e worker. Serviço do Cloud Run: uma app Web pode ser modelada como um serviço do Cloud Run. Cada serviço tem o seu próprio ponto final HTTPS e pode ser automaticamente dimensionado para cima ou para baixo de 0 a N com base no tráfego para o ponto final do seu serviço.
    Bases de dados O Heroku Postgres é a base de dados da Heroku como serviço (DaaS) baseada no PostgreSQL. O Cloud SQL é um serviço de base de dados gerido para bases de dados relacionais no Google Cloud.

    Implementar a app Web Tasks de exemplo no Heroku

    As secções seguintes mostram como configurar a interface de linhas de comando (CLI) para o Heroku, clonar o repositório de origem do GitHub e implementar a app no Heroku.

    Configure a interface de linhas de comando para o Heroku

    Este tutorial executa a CLI do Heroku no Cloud Shell e tem de ser autenticado através de uma chave da API do Heroku. Quando executada no Cloud Shell, a CLI do Heroku não pode autenticar-se através de uma palavra-passe ou da autenticação baseada na Web.

    Em alternativa, se executar o exemplo num terminal local, pode usar qualquer método de autenticação da CLI do Heroku. Quando executar o tutorial num terminal local, também tem de instalar a CLI do Google Cloud, o git e o Docker.

    1. Inicie sessão na consola Web do Heroku e, de seguida, na página de definições da conta, copie o valor da chave da API.

    2. No Cloud Shell, instale a CLI Heroku

    3. No Cloud Shell, autentique a CLI do Heroku. Quando lhe for pedida a palavra-passe, introduza o valor da chave da API que copiou da consola do Heroku e não a palavra-passe que usa para iniciar sessão na consola.

      heroku login --interactive
      

    Clone o repositório de origem

    1. No Cloud Shell, clone o repositório do GitHub da app Tasks de exemplo:

      git clone https://github.com/GoogleCloudPlatform/migrate-webapp-heroku-to-cloudrun-node.git
      
    2. Altere os diretórios para o diretório criado através da clonagem do repositório:

      cd migrate-webapp-heroku-to-cloudrun-node
      

      O diretório contém os seguintes ficheiros:

      • Um script Node.js denominado index.js com o código para as rotas publicadas pela app Web.
      • package.json e package-lock.json que descrevem as dependências da app Web. Tem de instalar estas dependências para que a app seja executada.
      • Um ficheiro Procfile que especifica o comando que a app executa no arranque. Crie um ficheiro Procfile para implementar a sua app no Heroku.
      • Um diretório views com o conteúdo HTML publicado pela app Web na rota "/".
      • Um ficheiro .gitignore.

    Implemente uma app no Heroku

    1. No Cloud Shell, crie uma app Heroku:

      heroku create
      

      Tome nota do nome criado para a app. Precisa deste valor no passo seguinte.

    2. Crie uma variável de ambiente para o nome da app Heroku:

      export APP_NAME=APP_NAME
      

      Substitua APP_NAME pelo nome da app devolvido pelo comando heroku create.

    3. Adicione o suplemento Heroku Postgres para aprovisionar uma base de dados PostgreSQL:

      heroku addons:create heroku-postgresql:mini
      
    4. Certifique-se de que o suplemento foi adicionado com êxito:

      heroku addons
      

      Se o suplemento Postgres tiver sido adicionado com êxito, é apresentada uma mensagem semelhante à seguinte:

      Add-on               Plan     Price       State
      -----------------    -----    --------    -----
      heroku-postgresql    mini     5$/month    created
      
    5. Implemente a app no Heroku:

      git push heroku master
      
    6. Execute o seguinte comando para confirmar o valor de DATABASE_URL.

      heroku config
      

      Anote o valor obtido para DATABASE_URL. Precisa deste valor no passo seguinte.

    7. Execute um contentor Docker.

      docker run -it --rm postgres psql "DATABASE_URL"
      

      Substitua DATABASE_URL pelo URL do Heroku Postgres que anotou no passo anterior.

    8. No contentor do Docker, crie a tabela TASKS com o seguinte comando:

      CREATE TABLE TASKS
      (DESCRIPTION TEXT NOT NULL);
      
    9. Saia do contentor:

      exit
      
    10. No Cloud Shell, execute o seguinte comando para obter o URL da Web da sua app Heroku:

      heroku info
      
    11. Abra o URL da Web numa janela do navegador. A app tem o seguinte aspeto: captura de ecrã (embora a sua versão não tenha as tarefas apresentadas):

      App de tarefas no navegador de Internet.

    12. Crie tarefas de exemplo na sua app a partir do navegador. Certifique-se de que as tarefas são obtidas a partir da base de dados e estão visíveis na IU.

    Preparar o código da app Web para a migração para o Cloud Run

    Esta secção detalha os passos que tem de concluir para preparar a sua app Web para a implementação no Cloud Run.

    Crie e publique o seu contentor Docker no Container Registry

    Precisa de uma imagem Docker para criar o contentor da app para que possa ser executado no Cloud Run. Pode criar o contentor manualmente ou através de Buildpacks.

    Crie o contentor manualmente

    1. No Cloud Shell, crie um Dockerfile no diretório criado pela clonagem do repositório para este tutorial:

      cat <<"EOF" > Dockerfile
      # Use the official Node image.
      # https://hub.docker.com/_/node
      FROM node:10-alpine
      
      # Create and change to the app directory.
      WORKDIR /app
      
      # Copying this separately prevents re-running npm install on every code change.
      COPY package*.json ./
      RUN npm install
      
      # Copy local code to the container image.
      COPY . /app
      
      # Configure and document the service HTTP port.
      ENV PORT 8080
      EXPOSE $PORT
      
      # Run the web service on container startup.
      CMD ["npm", "start"]
      EOF
      
    2. Crie o contentor com o Cloud Build e publique a imagem no Container Registry:

      gcloud builds submit --tag gcr.io/PROJECT_ID/APP_NAME:1 \
        --gcs-log-dir=gs://PROJECT_ID_cloudbuild
      
    3. Crie uma variável de ambiente para guardar o nome da imagem do Docker que criou:

      export IMAGE_NAME="gcr.io/PROJECT_ID/APP_NAME:1"
      

    Crie um contentor com Buildpacks

    1. No Cloud Shell, instale a CLI pack.

    2. Defina a CLI pack para usar o criador do Heroku por predefinição:

      pack config default-builder heroku/buildpacks:22
      
    3. Crie uma variável de ambiente para guardar o nome da imagem do Docker:

      export IMAGE_NAME=gcr.io/PROJECT_ID/APP_NAME:1
      
    4. Crie a imagem com o comando pack e envie ou publique a imagem para o Container Registry:

      pack build --publish $IMAGE_NAME
      

    Crie uma instância do Cloud SQL para PostgreSQL

    Cria uma instância do Cloud SQL para PostgreSQL para servir como back-end para a app Web. Neste tutorial, o PostgreSQL é mais adequado como a app de exemplo implementada no Heroku, que usa uma base de dados Postgres como back-end. Para efeitos desta app, a migração para o Cloud SQL para PostgreSQL a partir de um serviço Postgres gerido não requer alterações ao esquema.

    1. Prepare a sua rede para o Cloud SQL com um endereço IP privado.

      gcloud compute addresses create google-managed-services-default \
        --global \
        --purpose=VPC_PEERING \
        --prefix-length=16 \
        --description="peering range for CloudSQL Private Service Access" \
        --network=default
      
      gcloud services vpc-peerings connect \
        --service=servicenetworking.googleapis.com \
        --ranges=google-managed-services-default \
        --network=default \
        --project=PROJECT_ID
      
    2. Crie uma variável de ambiente denominada CLOUDSQL_DB_NAME para armazenar o nome da instância da base de dados que criar no passo seguinte:

      export CLOUDSQL_DB_NAME=tasks-db
      
    3. Crie a base de dados:

      gcloud sql instances create $CLOUDSQL_DB_NAME \
      --cpu=1 \
      --memory=4352Mib \
      --database-version=POSTGRES_15 \
      --region=us-central1 \
      --network default \
      --no-assign-ip
      

      A instância pode demorar alguns minutos a ser inicializada.

    4. Defina uma palavra-passe para o utilizador do Postgres:

      gcloud sql users set-password postgres \
          --instance=$CLOUDSQL_DB_NAME  \
          --password=POSTGRES_PASSWORD
      

      Substitua POSTGRES_PASSWORD pela palavra-passe que quer usar para a base de dados do Postgres.

    Importe dados para o Cloud SQL a partir do Heroku Postgres

    Existem vários padrões de migração que pode usar para migrar dados para o Cloud SQL. Geralmente, a melhor abordagem que requer pouco ou nenhum tempo de inatividade é configurar o Cloud SQL como uma réplica da base de dados que está a ser migrada e tornar o Cloud SQL a instância principal após a migração. O Heroku Postgres não suporta réplicas externas (seguidores). Por isso, neste tutorial, vai usar ferramentas de código aberto para migrar o esquema da app.

    Para a app Tasks neste tutorial, usa o utilitário pg_dump para exportar dados do Heroku Postgres para um contentor do Cloud Storage e, em seguida, importá-los para o Cloud SQL. Esta utilidade pode transferir dados entre versões homogéneas ou quando a versão da base de dados de destino é mais recente do que a da base de dados de origem.

    1. No Cloud Shell, obtenha as credenciais da base de dados para a sua base de dados Heroku Postgres associada à app de exemplo. Precisa destas credenciais no passo seguinte.

      heroku pg:credentials:url
      

      Este comando devolve a string de informações de ligação e o URL de ligação para a sua aplicação. A string de informações de ligação tem o seguinte formato:

      "dbname=DATABASE_NAME host=FQDN port=5432 user=USER_NAME password=PASSWORD_STRING sslmode=require"
      

      Precisa dos valores apresentados na string de ligação no passo seguinte.

      Para ver um exemplo de um valor FQDN (nome de domínio totalmente qualificado) numa string de informações de ligação, consulte a documentação do Heroku.

    2. Defina variáveis de ambiente para conter valores do Heroku que usa nos passos subsequentes:

      export HEROKU_PG_DBNAME=DATABASE_NAME
      export HEROKU_PG_HOST=FQDN
      export HEROKU_PG_USER=USER_NAME
      export HEROKU_PG_PASSWORD=PASSWORD_STRING
      

      Substitua o seguinte:

      • DATABASE_NAME: o nome da base de dados apresentado na string de informações.
      • FQDN: o FQDN apresentado na string de informações.
      • USER_NAME: o nome do utilizador apresentado na string de informações.
      • PASSWORD_STRING: a string da palavra-passe apresentada na string de informações.
    3. Crie uma cópia de segurança em formato SQL da sua base de dados Heroku Postgres:

      docker run \
        -it --rm \
        -e PGPASSWORD=$HEROKU_PG_PASSWORD \
        -v $(pwd):/tmp \
        --entrypoint "pg_dump" \
        postgres \
        -Fp \
        --no-acl \
        --no-owner \
        -h $HEROKU_PG_HOST \
        -U $HEROKU_PG_USER \
        $HEROKU_PG_DBNAME > herokudump.sql
      
    4. Crie uma variável de ambiente para armazenar o nome do seu contentor do Cloud Storage:

      export PG_BACKUP_BUCKET=gs://PROJECT_ID-pg-backup-bucket
      
    5. Crie um contentor do Cloud Storage:

      gcloud storage buckets create $PG_BACKUP_BUCKET \
        --location=us-central1 \
        --public-access-prevention \
        --uniform-bucket-level-access
      
    6. Carregue o ficheiro SQL para este contentor:

      gcloud storage cp herokudump.sql $PG_BACKUP_BUCKET/herokudump.sql
      
    7. Autorize a sua instância do Cloud SQL com as funções necessárias para importar o ficheiro SQL do contentor do Cloud Storage:

      gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \
        --role=roles/storage.objectAdmin
      
      gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \
        --role=roles/cloudsql.editor
      
    8. Importe o ficheiro SQL para a instância do Cloud SQL:

      gcloud sql import sql $CLOUDSQL_DB_NAME $PG_BACKUP_BUCKET/herokudump.sql \
        --database=postgres \
        --user=postgres
      

      Quando lhe for pedido do you want to continue (y/n), introduza "y".

    Como o Cloud Run acede à base de dados do Cloud SQL

    Tal como a app Web implementada no Heroku tem de se ligar à instância gerida do Heroku Postgres, o Cloud Run requer acesso ao Cloud SQL para poder ler e escrever dados.

    O Cloud Run comunica com o Cloud SQL através do proxy do Cloud SQL que é ativado e configurado automaticamente quando implementa o contentor no Cloud Run. A base de dados não precisa de ter endereços IP externos aprovados porque toda a comunicação que recebe é do proxy através de TCP seguro.

    O seu código tem de invocar operações de base de dados (como obter dados da base de dados ou escrever nela) invocando o proxy através de um socket UNIX.

    Uma vez que esta app Web está escrita em Node.js, usa a biblioteca pg-connection-string para analisar um URL da base de dados e criar um objeto config. A vantagem desta abordagem é que torna a ligação à base de dados de back-end integrada no Heroku e no Cloud Run.

    No passo seguinte, transmite o URL da base de dados como uma variável de ambiente quando implementa a app Web.

    Implemente a app de exemplo no Cloud Run

    1. No Cloud Shell, configure o acesso VPC sem servidor para permitir tráfego privado do Cloud Run para o Cloud SQL:

      gcloud compute networks subnets create serverless-connector-subnet \
      --network=default \
      --range=10.0.0.0/28 \
      --region=us-central1
      
      gcloud compute networks vpc-access connectors create serverless-connector \
      --region=us-central1 \
      --subnet=serverless-connector-subnet
      
    2. No Cloud Shell, crie uma variável de ambiente que contenha o nome de ligação da instância do Cloud SQL que criou:

      export DB_CONN_NAME=$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='value(connectionName)')
      
    3. Crie uma variável de ambiente denominada DATABASE_URL para conter a string de ligação para ligar ao proxy do Cloud SQL através de uma porta UNIX.

      export DATABASE_URL="socket:/cloudsql/${DB_CONN_NAME}?db=postgres&user=postgres&password=POSTGRES_PASSWORD"
      
    4. Crie uma conta de serviço para o Cloud Run com uma função do IAM para ligar à base de dados:

      gcloud iam service-accounts create sa-run-db-client
      
      gcloud projects add-iam-policy-binding PROJECT_ID \
          --member=serviceAccount:sa-run-db-client@PROJECT_ID.iam.gserviceaccount.com \
          --role=roles/cloudsql.client
      
    5. Implemente a app Web no Cloud Run:

      gcloud run deploy tasksapp-PROJECT_ID \
          --image=$IMAGE_NAME \
          --service-account=sa-run-db-client@PROJECT_ID.iam.gserviceaccount.com \
          --set-env-vars=DATABASE_URL=$DATABASE_URL \
          --add-cloudsql-instances $DB_CONN_NAME \
          --vpc-connector serverless-connector \
          --allow-unauthenticated
      
      

      O comando anterior também associa o seu contentor do Cloud Run à instância da base de dados do Cloud SQL que criou. O comando define uma variável de ambiente para o Cloud Run apontar para a string DATABASE_URL que criou no passo anterior.

    Testar a aplicação

    1. No Cloud Shell, obtenha o URL no qual o Cloud Run serve tráfego:

      gcloud run services list
      

      Também pode rever o serviço do Cloud Run na Google Cloud consola.

    2. Certifique-se de que a sua app Web está a aceitar pedidos HTTP navegando para o URL do serviço do Cloud Run.

    O Cloud Run cria ou inicia um novo contentor quando um pedido HTTP é enviado para o ponto final de publicação e se ainda não estiver a ser executado um contentor. Isto significa que o pedido que faz com que um novo contentor seja iniciado pode demorar um pouco mais a ser processado. Tendo em conta esse tempo adicional, considere o número de pedidos simultâneos que a sua app pode suportar e quaisquer requisitos de memória específicos que possa ter.

    Para esta app, usa as predefinições de simultaneidade, que permitem que um serviço do Cloud Run processe 80 pedidos em simultâneo a partir de um único contentor.

    Limpar

    Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial. Também pode eliminar os recursos criados no Heroku para este tutorial.

    Elimine o Google Cloud projeto

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Elimine a app Heroku

    Para eliminar a app de exemplo implementada no Heroku e o suplemento PostgreSQL associado, execute o seguinte comando:

    heroku apps:destroy -a APP_NAME
    

    O que se segue?