Jak wdrożyć witrynę z generatywnym interfejsem w Cloud Run

1. Wprowadzenie

Przegląd

W tym laboratorium utworzysz i wdrożysz witrynę, której treść jest generowana na bieżąco przez duże modele językowe Gemini od Google. Witryna będzie prostym nawigatorem w stylu „wybierz własną przygodę”, w którym możesz odkrywać tematy. Każde kliknięcie spowoduje wygenerowanie nowej strony z nowymi linkami na podstawie Twojego wyboru. Zbudujesz go za pomocą Node.js i Fastify, użyjesz pakietu Vertex AI SDK do wywoływania Gemini, wdrożysz go jako bezpieczną usługę przygotowaną do zastosowań produkcyjnych w Cloud Run i zabezpieczysz za pomocą Identity-Aware Proxy (IAP).

Jakie zadania wykonasz

  • Utwórz aplikację Fastify w Node.js, która korzysta z Vertex AI.
  • Wdrażanie aplikacji w Cloud Run ze źródła bez pliku Dockerfile.
  • Zabezpiecz punkt końcowy Cloud Run za pomocą Identity-Aware Proxy (IAP).

Czego się nauczysz

  • Jak używać pakietu Vertex AI SDK dla Node.js do generowania treści.
  • Jak wdrożyć aplikację Node.js w Cloud Run.
  • Jak zabezpieczyć aplikację Cloud Run za pomocą IAP.

2. Konfiguracja projektu

  1. Jeśli nie masz jeszcze konta Google, musisz je utworzyć.
    • Używaj konta osobistego zamiast konta służbowego lub szkolnego. Konta służbowe i szkolne mogą mieć ograniczenia, które uniemożliwiają włączenie interfejsów API potrzebnych do tego ćwiczenia.
  2. Zaloguj się w konsoli Google Cloud.
  3. Włącz płatności w konsoli Google Cloud.
  4. Utwórz nowy projekt lub użyj już istniejącego.
    • Jeśli zobaczysz błąd dotyczący limitu projektu, użyj ponownie istniejącego projektu lub usuń go, aby utworzyć nowy.

3. Otwórz edytor Cloud Shell

  1. Kliknij ten link, aby przejść bezpośrednio do edytora Cloud Shell
  2. Jeśli w dowolnym momencie pojawi się prośba o autoryzację, kliknij Autoryzuj, aby kontynuować. Kliknij, aby uwierzytelnić się w Cloud Shell
  3. Jeśli terminal nie pojawi się u dołu ekranu, otwórz go:
    • Kliknij Wyświetl.
    • Kliknij TerminalOtwieranie nowego terminala w edytorze Cloud Shell.
  4. W terminalu ustaw projekt za pomocą tego polecenia:
    • Format:
      gcloud config set project [PROJECT_ID]
      
    • Przykład:
      gcloud config set project lab-project-id-example
      
    • Jeśli nie pamiętasz identyfikatora projektu:
      • Aby wyświetlić listę wszystkich identyfikatorów projektów, użyj tego polecenia:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Ustawianie identyfikatora projektu w terminalu edytora Cloud Shell
  5. Powinien wyświetlić się ten komunikat:
    Updated property [core/project].
    
    Jeśli widzisz symbol WARNING i pojawia się pytanie Do you want to continue (Y/n)?, prawdopodobnie identyfikator projektu został wpisany nieprawidłowo. Naciśnij n, a następnie Enter i spróbuj ponownie uruchomić polecenie gcloud config set project.
  1. Ustaw zmienną środowiskową GOOGLE_CLOUD_PROJECT.
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    

4. Włącz interfejsy API

W terminalu włącz interfejsy API:

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

Jeśli pojawi się prośba o autoryzację, kliknij Autoryzuj, aby przejść dalej. Kliknij, aby uwierzytelnić się w Cloud Shell

Wykonanie tego polecenia może potrwać kilka minut, ale powinno ostatecznie wyświetlić komunikat o sukcesie podobny do tego:

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

5. Przygotowywanie projektu Node.js

  1. Utwórz folder o nazwie gen-ui-on-cloudrun, w którym będzie przechowywany kod źródłowy do wdrożenia:
    mkdir gen-ui-on-cloudrun && cd gen-ui-on-cloudrun
    
  2. Zainicjuj projekt Node.js:
    npm init -y
    
  3. Skonfiguruj projekt tak, aby używał modułów ES, i zdefiniuj skrypt startowy, wykonując te polecenia:
    npm pkg set type="module"
    
  4. Zainstaluj fastify dla serwera WWW i @google/genai dla pakietu Vertex AI SDK:
    npm install fastify @google/genai
    

6. Tworzenie kodu aplikacji

  1. Utwórz i otwórz nowy plik index.ts z kodem źródłowym aplikacji:
    cloudshell edit ~/gen-ui-on-cloudrun/index.ts
    
    Polecenie cloudshell edit otworzy plik index.ts w edytorze nad terminalem.
  2. Dodaj ten kod źródłowy serwera interfejsu generatywnego do pliku 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();
    

Ten kod konfiguruje serwer internetowy, który nasłuchuje żądań HTTP GET w ścieżce głównej (/). Gdy otrzyma żądanie, używa parametru zapytania nextPageDescription (lub wartości domyślnej) jako prompta dla modelu Gemini 2.5 Flash w Vertex AI. Model otrzymuje instrukcję SYSTEM_INSTRUCTION, aby zwracać stronę HTML zawierającą linki, z których każdy zawiera parametr nextPageDescription służący do generowania kolejnej strony.

7. Utwórz konto usługi

Aby uwierzytelnić się w interfejsie Vertex AI API, musisz mieć konto usługi dla usługi Cloud Run.

  1. Utwórz konto usługi o nazwie gen-navigator-sa:
    gcloud iam service-accounts create gen-navigator-sa --display-name="Generative Navigator Service Account"
    
  2. Przyznaj kontu usługi uprawnienia do korzystania z 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. Wdrożenie w Cloud Run

Teraz wdróż aplikację w Cloud Run bezpośrednio z kodu źródłowego, bez konieczności używania pliku Dockerfile.

  1. Aby wdrożyć aplikację, uruchom polecenie gcloud:
    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"
    
    Używamy tu kilku ważnych flag:
    • --source . --no-build --base-image=nodejs24: informuje Cloud Run, aby wdrożyć kod źródłowy z bieżącego katalogu, pominąć etap kompilacji i uruchomić aplikację przy użyciu wstępnie skompilowanego obrazu bazowego Node.js 24.
    • --no-allow-unauthenticated: dzięki temu tylko uwierzytelnieni użytkownicy mogą uzyskać dostęp do usługi.
    • --iap: Umożliwia to Identity-Aware Proxy (IAP) zarządzanie dostępem do aplikacji. IAP umożliwia kontrolowanie dostępu na podstawie tożsamości użytkownika i kontekstu, a nie tylko adresów IP.
  2. Po kilku minutach zobaczysz komunikat podobny do tego:
    Service [generative-web-navigator] revision [generative-web-navigator-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Aplikacja została wdrożona, ale musisz jeszcze skonfigurować IAP, aby umożliwić dostęp.

9. Konfigurowanie dostępu IAP

Gdy włączysz IAP w Cloud Run, IAP przechwytuje wszystkie żądania i wymaga od użytkowników uwierzytelnienia i autoryzacji, zanim będą mogli uzyskać dostęp do Twojej usługi. Aby to działało, musisz przyznać 2 uprawnienia:

  • Zezwól usłudze IAP na wywoływanie usługi Cloud Run.
  • Zezwól sobie (lub innym użytkownikom/grupom) na dostęp do aplikacji za pomocą zakupu w aplikacji.
  1. Uzyskaj numer projektu, który jest potrzebny do identyfikacji agenta usługi IAP:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
  2. Przypisz agentowi usługi IAP rolę roles/run.invoker w usłudze Cloud Run. Umożliwia to IAP wywoływanie Twojej usługi po uwierzytelnieniu i autoryzacji użytkownika.
    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. Przyznaj kontu użytkownika rolę roles/iap.httpsResourceAccessor. Umożliwia to dostęp do zasobów HTTPS zabezpieczonych przez 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. Testowanie aplikacji

  1. Uzyskaj adres URL wdrożonej usługi:
    gcloud run services describe generative-web-navigator --format='value(status.url)' --region=europe-west1
    
  2. Skopiuj adres URL i otwórz go w przeglądarce. Usługa jest zabezpieczona za pomocą IAP, więc jeśli nie jesteś zalogowany(-a), pojawi się prośba o zalogowanie się na konto Google. Po uwierzytelnieniu powinna się wyświetlić pierwsza automatycznie wygenerowana strona.
  3. Kliknij dowolny link, aby przejść do nowej strony, która zostanie wygenerowana przez AI na podstawie klikniętego linku.

Udało Ci się! Udało Ci się wdrożyć w Cloud Run witrynę z interfejsem generatywnym i zabezpieczyć ją za pomocą IAP.

11. Podsumowanie

Gratulacje! Udało Ci się wdrożyć i zabezpieczyć witrynę z generatywnym interfejsem użytkownika za pomocą Cloud Run, Vertex AI i IAP.

(Opcjonalnie) Zwalnianie miejsca

Jeśli chcesz zwolnić miejsce, usuwając utworzone zasoby, możesz usunąć projekt w chmurze, aby uniknąć dodatkowych opłat.

Cloud Run nie nalicza opłat, gdy usługa nie jest używana, ale może zostać pobrana należność za przechowywanie artefaktów kompilacji, jeśli zostały utworzone. Usunięcie projektu w chmurze spowoduje zaprzestanie naliczania opłat za wszelkie zasoby wykorzystywane w ramach tego projektu.

Jeśli chcesz, usuń projekt:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Możesz też usunąć niepotrzebne zasoby z dysku Cloud Shell. Możesz:

  1. Usuń katalog projektu ćwiczeń z programowania:
    rm -rf ~/gen-ui-on-cloudrun
    
  2. Ostrzeżenie! Tej czynności nie można cofnąć. Jeśli chcesz usunąć wszystko z Cloud Shell, aby zwolnić miejsce, możesz usunąć cały katalog domowy. Upewnij się, że wszystko, co chcesz zachować, jest zapisane w innym miejscu.
    sudo rm -rf $HOME