Cloud Run est le service serverless de Google Cloud pour les conteneurs. Vous déployez une image Docker et Google s'occupe de tout : scaling automatique de 0 à N, HTTPS, load balancing. Vous ne payez que pour les requêtes traitées.
brew install google-cloud-sdk ou cloud.google.com/sdkCloud Run : Service sans serveur (serverless) de Google Cloud qui exécute des conteneurs Docker. Vous ne gérez pas d'infrastructure — Google gère le scaling, la disponibilité et les certificats SSL automatiquement.
Serverless : Architecture où vous écrivez du code qui s'exécute en réponse à des événements, sans gérer de serveurs. Vous ne payez que pour le temps d'exécution réel.
Container : Package isolé contenant votre application, ses dépendances et sa configuration — toujours la même quel que soit l'environnement d'exécution.
Artifact Registry : Registre Docker géré par Google Cloud pour stocker vos images Docker privées de manière sécurisée.
Scale-to-zero : Capacité à réduire l'infrastructure à zéro quand il n'y a pas de requêtes, ce qui économise les coûts (vous ne payez rien quand votre API ne traite pas de requêtes).
Région : Zone géographique où s'exécute votre service (exemple : europe-west1 = Paris/Belgique). Plus proche = moins de latence.
Les commandes gcloud configurent votre environnement Google Cloud et activent les services nécessaires :
# Se connecter à Google Cloud
gcloud auth login
# Créer un nouveau projet (ou en utiliser un existant)
gcloud projects create mon-api-project --name="Mon API FastAPI"
# Définir le projet par défaut
gcloud config set project mon-api-project
# Activer les APIs nécessaires
gcloud services enable run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
# Configurer la région
gcloud config set run/region europe-west1 # Paris/Belgique
Notre API avec un endpoint de démonstration et support de l'environnement Cloud Run. L'important est que l'application écoute sur le port injecté par Cloud Run via la variable PORT :
from fastapi import FastAPI
from pydantic import BaseModel
import os
app = FastAPI(
title="Mon API Cloud Run",
version="1.0.0",
docs_url="/docs"
)
# Cloud Run injecte automatiquement PORT
PORT = int(os.getenv("PORT", "8080"))
class PredictionRequest(BaseModel):
text: str
class PredictionResponse(BaseModel):
sentiment: str
confidence: float
text: str
@app.get("/")
def root():
return {
"service": "Sentiment Analysis API",
"version": "1.0.0",
"environment": os.getenv("ENVIRONMENT", "production")
}
@app.post("/predict", response_model=PredictionResponse)
def predict(request: PredictionRequest):
"""Analyse de sentiment simplifiée pour la démonstration."""
positive_words = {'excellent', 'super', 'génial', 'parfait', 'bien', 'top'}
negative_words = {'mauvais', 'nul', 'terrible', 'horrible', 'décevant'}
words = set(request.text.lower().split())
pos_count = len(words & positive_words)
neg_count = len(words & negative_words)
if pos_count > neg_count:
return PredictionResponse(
sentiment="positif",
confidence=round(0.6 + pos_count * 0.1, 2),
text=request.text
)
elif neg_count > pos_count:
return PredictionResponse(
sentiment="négatif",
confidence=round(0.6 + neg_count * 0.1, 2),
text=request.text
)
return PredictionResponse(sentiment="neutre", confidence=0.55, text=request.text)
@app.get("/health")
def health():
return {"status": "healthy"}
PORT = int(os.getenv("PORT", "8080")) est cruciale : elle récupère le port injecté par Cloud Run. Cloud Run assigne dynamiquement un port (variable d'environnement PORT) — vous ne pouvez pas coder en dur 8080 car Cloud Run décide du port réellement utilisé. Si la variable n'existe pas (mode local), on utilise 8080 par défaut.
PORT unique à chaque conteneur. Si vous codez 8080 en dur, les conteneurs supplémentaires vont échouer (port déjà utilisé).
fastapi==0.111.0
uvicorn[standard]==0.29.0
pydantic==2.7.0
FROM python:3.11-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Cloud Run utilise la variable PORT injectée automatiquement
# On utilise sh -c pour permettre la substitution de variable
CMD exec uvicorn main:app --host 0.0.0.0 --port $PORT
$PORT dans votre conteneur. Votre application DOIT écouter sur ce port.Un registry est un entrepôt centralisé qui stocke vos images Docker. Cloud Run doit pouvoir accéder à votre image pour la déployer.
# Variables
PROJECT_ID="mon-api-project"
REGION="europe-west1"
REPO_NAME="mon-repo"
IMAGE_NAME="sentiment-api"
# Créer le registry Artifact Registry
gcloud artifacts repositories create $REPO_NAME \
--repository-format=docker \
--location=$REGION \
--description="Images Docker pour mes APIs"
# Configurer Docker pour s'authentifier à Artifact Registry
gcloud auth configure-docker $REGION-docker.pkg.dev
# Construire l'image avec le tag complet Artifact Registry
IMAGE_TAG=$REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/$IMAGE_NAME:v1
docker build -t $IMAGE_TAG .
# Pousser l'image
docker push $IMAGE_TAG
# Vérifier que l'image est dans le registry
gcloud artifacts docker images list $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME
docker login manuel).région-docker.pkg.dev/project/repo/image:tag).Cette commande déploie votre image Docker sur Cloud Run avec les configurations de ressources et d'accès :
gcloud run deploy sentiment-api \
--image=$IMAGE_TAG \
--platform=managed \
--region=$REGION \
--allow-unauthenticated \ # API publique
--min-instances=0 \ # Scale to zero (économique)
--max-instances=10 \ # Limite de scaling
--memory=512Mi \
--cpu=1 \
--concurrency=80 \ # Requêtes simultanées par instance
--set-env-vars="ENVIRONMENT=production" \
--port=8080
$PORT, ici 8080 par défaut).
SERVICE_URL=$(gcloud run services describe sentiment-api \
--region=$REGION \
--format='value(status.url)')
# Test endpoint racine
curl $SERVICE_URL
# Test prédiction
curl -X POST $SERVICE_URL/predict \
-H "Content-Type: application/json" \
-d '{"text": "Ce produit est excellent et super efficace"}'
# {"sentiment":"positif","confidence":0.8,"text":"Ce produit est excellent et super efficace"}
Au lieu de construire et pousser manuellement, Cloud Run peut compiler votre code directement via Cloud Build :
# Depuis le dossier contenant votre Dockerfile
# Cloud Build construit l'image et déploie automatiquement
gcloud run deploy sentiment-api \
--source . \
--region=europe-west1 \
--allow-unauthenticated
Pour les données sensibles (clés API, tokens), utilisez Secret Manager au lieu de les coder en dur :
# Créer un secret dans Secret Manager
echo -n "ma-cle-api-secrete" | gcloud secrets create API_KEY \
--data-file=- \
--replication-policy=automatic
# Déployer avec le secret monté comme variable d'environnement
gcloud run deploy sentiment-api \
--image=$IMAGE_TAG \
--region=$REGION \
--set-secrets="API_KEY=API_KEY:latest" \
--set-env-vars="ENVIRONMENT=production"
API_KEY dans votre conteneur (chiffré jusqu'au runtime). Seul votre code a accès à sa vraie valeur.
Trois options pour déployer une application — chacune avec ses usages :
# Cloud Run (serverless)
✅ APIs et microservices HTTP stateless
✅ Trafic variable / imprévisible
✅ Démarrage rapide sans infra à gérer
✅ Scale to zero = économique pour les petites charges
✅ Facturé à la requête (pas de coût fixe)
❌ Pas de connexions WebSocket longues durée
❌ Limité à 60 min par requête
🎯 IDÉAL POUR : API REST, webhooks, petites apps avec pic de trafic
# Kubernetes (orchestration)
✅ Applications avec état (bases de données, caches)
✅ Workloads complexes (jobs, workers, CronJobs)
✅ Contrôle total sur le réseau, le stockage
✅ Multi-cloud / on-premise
✅ Adapté aux équipes DevOps matures
❌ Complexité d'administration élevée
❌ Toujours des noeuds actifs = coût fixe
🎯 IDÉAL POUR : Applications complexes, services critiques, trafic constant
# VPS / VM dédiée
✅ Contrôle total (SSH, sudo, installer quoi on veut)
✅ Pas de contraintes de temps d'exécution
✅ Moins cher pour trafic constant prévisible
❌ Vous gérez OS, updates, sécurité, scaling manuel
❌ Toujours actif = coût fixe même sans trafic
🎯 IDÉAL POUR : Applications legacy, besoin de contrôle bas niveau, équipes très réduites