درس 8 — Production et projet final

Passer en production avec Cloud Run

6 دقائق قراءة

هذا المحتوى غير مترجم بعد. تُعرض النسخة الأصلية.

Passer en production avec Cloud Run

Cloud Run en trois phrases

Cloud Run exécute votre application dans un conteneur (un paquet qui contient le code, Python et les dépendances, décrit par un Dockerfile). Il lui donne une adresse HTTPS, démarre des copies (instances) quand les requêtes arrivent et les arrête quand il n'y en a plus. Vous payez à l'usage : au repos, avec zéro instance, le coût de calcul est nul.

flowchart LR
  S["Dossier files/ + Dockerfile"] -->|"gcloud run deploy --source"| B["Cloud Build : construit l'image"]
  B --> R["Artifact Registry : stocke l'image"]
  R --> C["Cloud Run : service HTTPS"]
  U["Utilisateurs"] --> C
  C -->|"compte de service"| V["Vertex AI : Gemini"]
  C -->|"stdout JSON"| L["Cloud Logging"]

Le conteneur

files/Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Cloud Run fournit le port dans la variable PORT (8080 par défaut).
CMD exec uvicorn app:app --host 0.0.0.0 --port ${PORT:-8080}

Les fichiers .dockerignore et .gcloudignore excluent .env et journal.jsonl : la clé ne part jamais dans l'image.

Quelle identité pour appeler Gemini ?

OptionCommentQuand
Vertex AI + compte de service (testée ici)GOOGLE_GENAI_USE_VERTEXAI=TRUE, aucune clé : le service s'authentifie avec son compte de service (l'identité Google Cloud de l'application)recommandé sur Google Cloud
Clé d'API dans Secret Managergcloud secrets create, puis --set-secrets GOOGLE_API_KEY=nom-du-secret:latestvous restez sur l'API Gemini (non testée dans ce lab)
Clé en variable d'environnement en clair--set-env-vars GOOGLE_API_KEY=...jamais : visible par quiconque lit la configuration du service

Le code ne change pas : genai.Client() lit ces variables. Seul le nom du modèle change, car le catalogue diffère entre l'API Gemini et Vertex AI (ici gemini-2.5-flash, disponible sur Vertex AI en europe-west1).

Déployer

terminal (dans files/)
gcloud run deploy lab-chatbot-metier --source . \
  --region europe-west1 --project VOTRE_PROJET \
  --labels formation-lab=chatbot-metier \
  --set-env-vars GOOGLE_GENAI_USE_VERTEXAI=TRUE,GOOGLE_CLOUD_PROJECT=VOTRE_PROJET,GOOGLE_CLOUD_LOCATION=europe-west1,MODEL=gemini-2.5-flash \
  --no-allow-unauthenticated --max-instances 1
  • --source . : Cloud Build construit l'image à partir du Dockerfile, sans Docker sur votre poste.
  • --no-allow-unauthenticated : seules les personnes autorisées (avec un jeton) peuvent appeler le service, idéal pour un test. Pour un vrai chatbot public, il faudra --allow-unauthenticated et une limite de débit.
  • --max-instances 1 : plafonne la dépense en cas d'abus.
  • Le compte de service du service doit avoir le rôle Utilisateur Vertex AI (roles/aiplatform.user).

Pourquoi ne pas passer la clé d'API avec --set-env-vars ?

La mémoire de conversation d'Alti est en RAM. Que se passe-t-il sur Cloud Run avec 3 instances ?

Nettoyer

Un service Cloud Run au repos ne coûte presque rien, mais l'image stockée, si. Supprimez tout ce que le déploiement a créé :

terminal
gcloud run services delete lab-chatbot-metier --region europe-west1 --project VOTRE_PROJET --quiet
gcloud artifacts docker images delete \
  europe-west1-docker.pkg.dev/VOTRE_PROJET/cloud-run-source-deploy/lab-chatbot-metier \
  --delete-tags --project VOTRE_PROJET --quiet
gcloud storage rm -r gs://run-sources-VOTRE_PROJET-europe-west1/services/lab-chatbot-metier/
# Vérification : ces commandes ne doivent plus rien afficher pour lab-chatbot-metier
gcloud run services list --region europe-west1 --project VOTRE_PROJET | grep chatbot
gcloud artifacts docker images list europe-west1-docker.pkg.dev/VOTRE_PROJET/cloud-run-source-deploy | grep chatbot

Exercice : rendre le service public sans se ruiner

Listez trois protections à ajouter avant de passer en --allow-unauthenticated.

Voir la solution
  1. Plafonds : --max-instances bas et une alerte de budget sur le projet.
  2. Limite de débit par adresse IP ou par session (par exemple avec Cloud Armor devant un équilibreur de charge, ou un compteur simple dans l'application) : un robot ne doit pas pouvoir enchaîner des milliers de questions.
  3. Limites d'entrée déjà en place : max_length=2000 sur le message, mémoire limitée à 10 messages, journal masqué.

On peut aussi exiger une vérification anti-robot (reCAPTCHA) sur la page.

Résultat obtenu

Déploiement réel le 2026-10-15 (projet de test, europe-west1), puis appels avec un jeton d'identité :

sortie réelle, 2026-10-15
Service [lab-chatbot-metier] revision [lab-chatbot-metier-00001-vnp] has been deployed and is serving 100 percent of traffic.

$ curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $URL/sante
{"ok":true,"modele":"gemini-2.5-flash"}
$ curl -s -o /dev/null -w "%{http_code}" $URL/sante          # sans jeton
403
$ curl -N -X POST $URL/chat -H "Authorization: Bearer ..." -H 'Content-Type: application/json' -d '{"session":"cloudrun","message":"Combien coûte la carte 10 entrées ?"}'
La carte 10 entrées coûte 120 €. Elle est valable 6 mois et donne accès uniquement au plateau.

Les deux événements correspondants, lus dans Cloud Logging. Le premier essai a reçu un 429 (quota Vertex AI partagé, épuisé à ce moment-là) : après deux réessais, l'utilisateur a reçu le message d'excuse ; le second a réussi en moins d'une seconde.

gcloud logging read ... jsonPayload.type=
{"jsonPayload": {"erreur": null, "latence_ms": 923, "modele": "gemini-2.5-flash", "question": "Combien coûte la carte 10 entrées ?"}, "timestamp": "2026-10-15T14:35:39.740410Z"}
{"jsonPayload": {"erreur": "429 RESOURCE_EXHAUSTED", "latence_ms": 6985, "modele": "gemini-2.5-flash", "question": "Combien coûte la carte 10 entrées ?"}, "timestamp": "2026-10-15T14:34:43.641351Z"}

Puis service, image et sources supprimés ; les deux commandes de vérification n'affichent plus rien.

Je sais faire

  • Expliquer conteneur, instance et compte de service
  • Déployer avec gcloud run deploy --source sans exposer de clé
  • Retrouver les échanges dans Cloud Logging
  • Supprimer service, image et sources, et vérifier la suppression
التالي