Como implantar um site de interface generativa no Cloud Run

1. Introdução

Visão geral

Neste laboratório, você vai criar e implantar um site cujo conteúdo é gerado na hora pelos modelos de linguagem grandes do Gemini do Google. O site será um navegador simples no estilo "escolha sua própria aventura" para explorar tópicos. Cada clique vai gerar uma nova página com novos links com base na sua seleção. Você vai criar isso com Node.js e Fastify, usar o SDK da Vertex AI para chamar o Gemini, implantar como um serviço seguro e pronto para produção no Cloud Run e proteger usando o Identity-Aware Proxy (IAP).

Atividades deste laboratório

  • Crie um aplicativo Node.js Fastify que use a Vertex AI.
  • Implante o aplicativo no Cloud Run a partir da origem sem um Dockerfile.
  • Proteja o endpoint do Cloud Run usando o Identity-Aware Proxy (IAP).

O que você vai aprender

  • Como usar o SDK da Vertex AI para Node.js para gerar conteúdo.
  • Como implantar um aplicativo Node.js no Cloud Run.
  • Como proteger um aplicativo do Cloud Run com o IAP.

2. Configuração do projeto

  1. Se você ainda não tiver uma Conta do Google, crie uma.
    • Use uma conta pessoal em vez de uma conta escolar ou de trabalho. As contas escolares e de trabalho podem ter restrições que impedem a ativação das APIs necessárias para este laboratório.
  2. Faça login no Console do Google Cloud.
  3. Ative o faturamento no console do Cloud.
    • A conclusão deste laboratório custa menos de US $1 em recursos do Cloud.
    • Siga as etapas no final deste laboratório para excluir recursos e evitar mais cobranças.
    • Novos usuários podem aproveitar o teste sem custos financeiros de US$300.
  4. Crie um projeto ou reutilize um projeto existente.
    • Se você receber um erro sobre a cota do projeto, reutilize ou exclua um projeto para criar outro.

3. Abrir editor do Cloud Shell

  1. Clique neste link para navegar diretamente até o editor do Cloud Shell.
  2. Se for preciso autorizar em algum momento, clique em Autorizar para continuar. Clique para autorizar o Cloud Shell
  3. Se o terminal não aparecer na parte de baixo da tela, abra-o:
    • Clique em Visualizar.
    • Clique em TerminalAbrir um novo terminal no editor do Cloud Shell.
  4. No terminal, defina o projeto com este comando:
    • Formato:
      gcloud config set project [PROJECT_ID]
      
    • Exemplo:
      gcloud config set project lab-project-id-example
      
    • Se você não se lembrar do ID do projeto:
      • Para listar todos os IDs de projeto, use:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Definir o ID do projeto no terminal do Editor do Cloud Shell
  5. Você vai receber esta mensagem:
    Updated property [core/project].
    
    Se você vir um WARNING e for perguntado Do you want to continue (Y/n)?, provavelmente inseriu o ID do projeto incorretamente. Pressione n, Enter e tente executar o comando gcloud config set project novamente.
  1. Defina a variável de ambiente GOOGLE_CLOUD_PROJECT.
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    

4. Ativar APIs

No terminal, ative as APIs:

gcloud services enable \
  run.googleapis.com \
  aiplatform.googleapis.com \
  cloudresourcemanager.googleapis.com \
  iap.googleapis.com

Se for preciso autorizar, clique em Autorizar para continuar. Clique para autorizar o Cloud Shell

Esse comando pode levar alguns minutos para ser concluído, mas vai gerar uma mensagem de sucesso semelhante a esta:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

5. Preparar o projeto Node.js

  1. Crie uma pasta chamada gen-ui-on-cloudrun para armazenar o código-fonte da implantação:
    mkdir gen-ui-on-cloudrun && cd gen-ui-on-cloudrun
    
  2. Inicialize um projeto Node.js:
    npm init -y
    
  3. Configure o projeto para usar módulos ES e defina um script de inicialização executando estes comandos:
    npm pkg set type="module"
    
  4. Instale fastify para o servidor da Web e @google/genai para o SDK da Vertex AI:
    npm install fastify @google/genai
    

6. Criar o código do aplicativo

  1. Crie e abra um novo arquivo index.ts para o código-fonte do aplicativo:
    cloudshell edit ~/gen-ui-on-cloudrun/index.ts
    
    O comando cloudshell edit vai abrir o arquivo index.ts no editor acima do terminal.
  2. Adicione o seguinte código-fonte do servidor de interface generativa ao arquivo index.ts:
    import fastifyLib from 'fastify';
    import { GoogleGenAI } from '@google/genai';
    
    const fastify = fastifyLib({ logger: true });
    
    const ai = new GoogleGenAI({
        vertexai: true,
        project: process.env.GOOGLE_CLOUD_PROJECT,
        location: process.env.GOOGLE_CLOUD_LOCATION || 'europe-west1',
    });
    
    const SYSTEM_INSTRUCTION = `The user should have submitted an html page and the id of the element just clicked.
    Given the next page description, create a new webpage with a link back to "Start Over" (the / route), a brief overview of the topic, and a list of clickable link elements related to the page.
    When an element is clicked, the webpage should link to the base route / with the nextPageDescription as a query string parameter.
    All information needed to generate the next page should be included in the nextPageDescription without additional context.
    Each nextPageDescription should be less than 1500 characters.
    
    Example:
    If the current HTML page is for a small pet store, it might include a link to an "About" page.
    The href for the about page link should be /?nextPageDescription=about%20page%20for%20small%20pet%20store%20website
    
    All responses should be valid HTML without markdown backticks.`;
    
    interface QueryParams {
        nextPageDescription?: string;
    }
    
    fastify.get<{ Querystring: QueryParams }>('/', async (request, reply) => {
        const {
            nextPageDescription = 'A web page with interesting fun facts where I can select a fact to learn more about that topic.'
        } = request.query;
    
        try {
            const response = await ai.models.generateContent({
                model: 'gemini-2.5-flash',
                contents: nextPageDescription,
                config: {
                    systemInstruction: SYSTEM_INSTRUCTION,
                    temperature: 0.9,
                }
            });
    
            reply.type('text/html; charset=utf-8').send(response.text);
        } catch (error: any) {
            request.log.error(error);
            reply.status(500).send('An error occurred calling the AI.');
        }
    });
    
    const start = async () => {
        try {
            await fastify.listen({ port: Number(process.env.PORT) || 8080, host: '0.0.0.0' });
        } catch (err) {
            fastify.log.error(err);
            process.exit(1);
        }
    };
    
    start();
    

Esse código configura um servidor da Web que fica aguardando solicitações HTTP GET no caminho raiz (/). Quando uma solicitação é recebida, ela usa o parâmetro de consulta nextPageDescription (ou um valor padrão) como um comando para o modelo Gemini 2.5 Flash pela Vertex AI. O modelo é instruído por SYSTEM_INSTRUCTION a retornar uma página HTML com links, em que cada um inclui um nextPageDescription para gerar a página seguinte.

7. Criar a conta de serviço

Você precisa de uma conta de serviço para que seu serviço do Cloud Run faça a autenticação com a API Vertex AI.

  1. Crie uma conta de serviço chamada gen-navigator-sa:
    gcloud iam service-accounts create gen-navigator-sa --display-name="Generative Navigator Service Account"
    
  2. Conceda à conta de serviço permissão para usar a Vertex AI:
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role="roles/aiplatform.user"
    

8. Implantar no Cloud Run

Agora implante o aplicativo no Cloud Run diretamente do código-fonte, sem precisar de um Dockerfile.

  1. Execute o comando gcloud para implantar o aplicativo:
    cd ~/gen-ui-on-cloudrun
    gcloud beta run deploy generative-web-navigator \
        --source . \
        --no-build \
        --base-image=nodejs24 \
        --command="node" \
        --args="index.ts" \
        --region=europe-west1 \
        --no-allow-unauthenticated \
        --iap \
        --service-account="gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --set-env-vars GOOGLE_CLOUD_PROJECT="$GOOGLE_CLOUD_PROJECT",GOOGLE_CLOUD_LOCATION="europe-west1"
    
    Usamos algumas flags importantes aqui:
    • --source . --no-build --base-image=nodejs24: informa ao Cloud Run para implantar o código-fonte do diretório atual, pular a fase de build e executar o aplicativo usando uma imagem de base do Node.js 24 pré-criada.
    • --no-allow-unauthenticated: isso garante que apenas usuários autenticados possam acessar o serviço.
    • --iap: permite que o Identity-Aware Proxy (IAP) gerencie o acesso ao seu aplicativo. Com o IAP, você controla o acesso com base na identidade e no contexto do usuário, em vez de apenas endereços IP.
  2. Depois de alguns minutos, você vai ver uma mensagem como esta:
    Service [generative-web-navigator] revision [generative-web-navigator-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Você implantou o aplicativo, mas ainda precisa configurar o IAP para permitir o acesso.

9. Configurar o acesso do IAP

Quando você ativa o IAP no Cloud Run, ele intercepta todas as solicitações e exige que os usuários se autentiquem e sejam autorizados antes de acessar seu serviço. Para isso, é necessário conceder duas permissões:

  • Permita que o próprio serviço do IAP invoque seu serviço do Cloud Run.
  • Permita que você (ou outros usuários/grupos) acessem o aplicativo pelo IAP.
  1. Consiga o número do projeto, que é necessário para identificar o agente de serviço da IAP:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
  2. Conceda ao agente de serviço da IAP o papel roles/run.invoker no seu serviço do Cloud Run. Isso permite que o IAP invoque seu serviço depois de autenticar e autorizar um usuário.
    gcloud run services add-iam-policy-binding generative-web-navigator \
        --region=europe-west1 \
        --member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-iap.iam.gserviceaccount.com" \
        --role="roles/run.invoker"
    
  3. Conceda à sua conta de usuário o papel roles/iap.httpsResourceAccessor. Isso permite acessar recursos HTTPS protegidos pelo IAP.
    gcloud beta iap web add-iam-policy-binding \
        --resource-type=cloud-run \
        --region=europe-west1 \
        --service=generative-web-navigator \
        --member="user:$(gcloud config get-value account)" \
        --role="roles/iap.httpsResourceAccessor"
    

10. Testar o aplicativo

  1. Consiga o URL do serviço implantado:
    gcloud run services describe generative-web-navigator --format='value(status.url)' --region=europe-west1
    
  2. Copie e abra o URL no navegador da Web. Como o serviço é protegido com o IAP, você vai precisar fazer login com sua Conta do Google se ainda não tiver feito isso. Depois da autenticação, a primeira página gerada automaticamente vai aparecer.
  3. Clique em qualquer link para navegar até uma nova página, que será gerada pela IA com base no link clicado.

Você conseguiu! Você implantou um site de interface generativa no Cloud Run e o protegeu usando o IAP.

11. Conclusão

Parabéns! Você implantou e protegeu um site de interface generativa usando o Cloud Run, a Vertex AI e o IAP.

(Opcional) Limpar

Se quiser liberar espaço do que você criou, exclua o projeto na nuvem para evitar cobranças adicionais.

Embora o Cloud Run não gere custos quando o serviço não está em uso, é possível receber cobranças pelo armazenamento de artefatos de build, se algum tiver sido criado. A exclusão do projeto na nuvem interrompe o faturamento de todos os recursos usados nele.

Se quiser, exclua o projeto:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Você também pode excluir recursos desnecessários do disco do Cloud Shell. Você pode:

  1. Exclua o diretório do projeto do codelab:
    rm -rf ~/gen-ui-on-cloudrun
    
  2. Aviso: Não é possível desfazer a próxima ação. Se você quiser excluir tudo no Cloud Shell para liberar espaço, exclua todo o diretório inicial. Tenha cuidado para que tudo o que você quer manter seja salvo em outro lugar.
    sudo rm -rf $HOME