Как развернуть веб-сайт с генеративным пользовательским интерфейсом на Cloud Run

1. Введение

Обзор

В этой лабораторной работе вы создадите и развернете веб-сайт, контент которого будет генерироваться в режиме реального времени с помощью больших языковых моделей Google Gemini. Веб-сайт будет представлять собой простой навигатор в стиле «выбери свой путь», где каждый клик будет генерировать новую страницу с новыми ссылками в зависимости от вашего выбора. Вы будете создавать его с помощью Node.js и Fastify, использовать SDK Vertex AI для вызова Gemini, развернете его как безопасный, готовый к использованию в производственной среде сервис на Cloud Run и защитите его с помощью Identity-Aware Proxy (IAP).

Что вы будете делать

  • Создайте приложение Node.js Fastify, использующее Vertex AI.
  • Разверните приложение в Cloud Run из исходного кода без Dockerfile.
  • Защитите конечную точку Cloud Run с помощью прокси-сервера с поддержкой идентификации (Identity-Aware Proxy, IAP).

Что вы узнаете

  • Как использовать SDK Vertex AI для Node.js для генерации контента.
  • Как развернуть приложение Node.js в Cloud Run.
  • Как защитить приложение Cloud Run с помощью IAP.

2. Настройка проекта

  1. Если у вас еще нет учетной записи Google, вам необходимо ее создать .
    • Используйте личный аккаунт вместо рабочего или учебного. Рабочие и учебные аккаунты могут иметь ограничения, которые не позволят вам включить API, необходимые для этой лабораторной работы.
  2. Войдите в консоль Google Cloud .
  3. Включите выставление счетов в облачной консоли.
    • Выполнение этой лабораторной работы должно обойтись менее чем в 1 доллар США в виде облачных ресурсов.
    • В конце этой лабораторной работы вы можете выполнить действия по удалению ресурсов, чтобы избежать дальнейших списаний средств.
    • Новые пользователи могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .
  4. Создайте новый проект или выберите вариант повторного использования существующего проекта.
    • Если вы видите ошибку, связанную с квотой проекта, используйте существующий проект повторно или удалите существующий проект, чтобы создать новый.

3. Откройте редактор Cloud Shell.

  1. Нажмите на эту ссылку, чтобы перейти непосредственно в редактор Cloud Shell.
  2. Если сегодня вам будет предложено авторизоваться, нажмите «Авторизовать» , чтобы продолжить. Нажмите, чтобы авторизовать Cloud Shell.
  3. Если терминал не отображается внизу экрана, откройте его:
    • Нажмите «Просмотреть».
    • Нажмите «Терминал» Откройте новый терминал в редакторе Cloud Shell.
  4. В терминале настройте свой проект с помощью этой команды:
    • Формат:
      gcloud config set project [PROJECT_ID]
      
    • Пример:
      gcloud config set project lab-project-id-example
      
    • Если вы не помните идентификатор своего проекта:
      • Вы можете вывести список всех идентификаторов ваших проектов с помощью:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Установите идентификатор проекта в терминале редактора Cloud Shell.
  5. Вы должны увидеть следующее сообщение:
    Updated property [core/project].
    
    Если вы видите WARNING и вас спрашивают Do you want to continue (Y/n)? , то, скорее всего, вы неправильно ввели идентификатор проекта. Нажмите n , затем Enter и попробуйте снова выполнить команду gcloud config set project .
  1. Установите переменную среды GOOGLE_CLOUD_PROJECT
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    

4. Включите API.

В терминале включите API:

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

Если появится запрос на авторизацию, нажмите «Авторизовать» , чтобы продолжить. Нажмите, чтобы авторизовать Cloud Shell.

Выполнение этой команды может занять несколько минут, но в итоге должно отобразиться сообщение об успешном завершении, похожее на это:

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

5. Подготовьте свой проект Node.js.

  1. Создайте папку с именем gen-ui-on-cloudrun для хранения исходного кода, необходимого для развертывания:
    mkdir gen-ui-on-cloudrun && cd gen-ui-on-cloudrun
    
  2. Инициализация проекта Node.js:
    npm init -y
    
  3. Настройте проект для использования модулей Elasticsearch и определите скрипт запуска, выполнив следующие команды:
    npm pkg set type="module"
    
  4. Установите fastify в качестве веб-сервера и @google/genai для Vertex AI SDK:
    npm install fastify @google/genai
    

6. Создайте код приложения.

  1. Создайте и откройте новый файл index.ts для исходного кода приложения:
    cloudshell edit ~/gen-ui-on-cloudrun/index.ts
    
    Команда cloudshell edit откроет файл index.ts в редакторе, расположенном над терминалом.
  2. Добавьте следующий исходный код генеративного пользовательского интерфейса сервера в файл 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();
    

Этот код настраивает веб-сервер, который прослушивает HTTP GET-запросы по корневому пути ( / ). При получении запроса он использует параметр запроса nextPageDescription (или значение по умолчанию) в качестве подсказки для модели Gemini 2.5 Flash через Vertex AI. Модель получает указание от SYSTEM_INSTRUCTION вернуть HTML-страницу, содержащую ссылки, где каждая ссылка включает nextPageDescription для генерации следующей страницы.

7. Создайте учетную запись службы.

Для аутентификации в API Vertex AI вашему сервису Cloud Run необходима учетная запись службы.

  1. Создайте учетную запись службы с именем gen-navigator-sa :
    gcloud iam service-accounts create gen-navigator-sa --display-name="Generative Navigator Service Account"
    
  2. Предоставьте учетной записи службы разрешение на использование 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. Развертывание в облаке.

Теперь вы можете развернуть приложение в Cloud Run непосредственно из исходного кода, без необходимости использования Dockerfile.

  1. Для развертывания приложения выполните команду 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"
    
    Здесь мы используем несколько важных флагов:
    • --source . --no-build --base-image=nodejs24 : Эта команда указывает Cloud Run развернуть исходный код из текущего каталога, пропустить этап сборки и запустить приложение, используя предварительно собранный базовый образ Node.js 24.
    • --no-allow-unauthenticated : Это гарантирует, что доступ к сервису будет только у аутентифицированных пользователей.
    • --iap : Эта опция позволяет Identity-Aware Proxy (IAP) управлять доступом к вашему приложению. IAP позволяет контролировать доступ на основе идентификации пользователя и контекста, а не только IP-адресов.
  2. Через несколько минут вы увидите сообщение следующего вида:
    Service [generative-web-navigator] revision [generative-web-navigator-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Вы развернули приложение, но вам еще необходимо настроить IAP для предоставления доступа.

9. Настройка доступа IAP

При включении IAP в Cloud Run, IAP перехватывает все запросы и требует от пользователей аутентификации и авторизации перед доступом к вашему сервису. Для этого необходимо предоставить два разрешения:

  • Разрешите самой службе IAP вызывать вашу службу Cloud Run.
  • Разрешите себе (или другим пользователям/группам) доступ к приложению через встроенные покупки.
  1. Получите номер своего проекта, который необходим для идентификации агента службы IAP:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
  2. Предоставьте агенту службы IAP роль roles/run.invoker для вашей службы Cloud Run. Это позволит IAP вызывать вашу службу после аутентификации и авторизации пользователя.
    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. Предоставьте своей учетной записи пользователя роль roles/iap.httpsResourceAccessor . Это позволит вам получить доступ к ресурсам HTTPS, защищенным 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. Протестируйте приложение.

  1. Получите URL-адрес развернутой вами службы:
    gcloud run services describe generative-web-navigator --format='value(status.url)' --region=europe-west1
    
  2. Скопируйте URL-адрес и откройте его в веб-браузере. Поскольку сервис защищен с помощью встроенных покупок (IAP), вам будет предложено войти в свою учетную запись Google, если вы еще не авторизованы. После аутентификации вы должны увидеть первую автоматически сгенерированную страницу.
  3. Нажмите на любую ссылку, чтобы перейти на новую страницу, которая будет сгенерирована искусственным интеллектом на основе нажатой вами ссылки!

У вас получилось! Вы успешно развернули веб-сайт с генеративным пользовательским интерфейсом в Cloud Run и защитили его с помощью IAP.

11. Заключение

Поздравляем! Вы успешно развернули и защитили веб-сайт с генеративным пользовательским интерфейсом, используя Cloud Run, Vertex AI и IAP.

(Необязательно) Уборка

Если вы хотите удалить созданный вами проект из облака, вы можете сделать это, чтобы избежать дополнительных расходов.

Хотя Cloud Run не взимает плату, когда услуга не используется, с вас все равно может взиматься плата за хранение артефактов сборки, если таковые были созданы. Удаление вашего проекта Cloud прекращает выставление счетов за все ресурсы, используемые в этом проекте.

При желании вы можете удалить проект:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Также вы можете удалить ненужные ресурсы с диска Cloudshell. Для этого выполните следующие действия:

  1. Удалите каталог проекта codelab:
    rm -rf ~/gen-ui-on-cloudrun
    
  2. Внимание! Следующее действие необратимо! Если вы хотите удалить все данные в Cloud Shell, чтобы освободить место, вы можете удалить всю свою домашнюю директорию . Будьте внимательны и убедитесь, что все, что вы хотите сохранить, сохранено в другом месте.
    sudo rm -rf $HOME