Déployer un conteneur sur une plateforme managée

Première leçon du cours Déployer une application sur le cloud, en accès libre : environ 20 minutes, 3 exercices et 3 questions de quiz. C'est la leçon de base du catalogue ; dans l'espace étudiant, elle est réécrite pour ton profil.

Objectifs

  • Déployer une image de conteneur sur un service managé (Cloud Run) en ligne de commande
  • Comprendre révisions, répartition du trafic, mise à l'échelle et démarrage à froid
  • Revenir à une révision précédente sans reconstruire l'image

Conteneurs managésRévisions et traficMise à l'échelle automatique

Dans le cours Docker, vous avez produit une image propre, taguée et publiée dans un registre. Reste à la faire tourner quelque part. Une plateforme de conteneurs managée prend votre image et s’occupe du reste : machines, système d’exploitation, certificat HTTPS, répartition de charge et mise à l’échelle. Vous ne gérez plus de serveur, seulement un service.

Ce cours utilise Google Cloud et sa CLI gcloud pour les exemples, parce que ses commandes sont courtes et lisibles. Les notions sont les mêmes ailleurs :

Besoin Google Cloud AWS Azure
Conteneurs managés Cloud Run App Runner, ECS sur Fargate Container Apps
Registre d’images Artifact Registry ECR Container Registry

Préparer le projet

gcloud config set project atelier-notes-prod      # projet fictif
gcloud config set run/region europe-west1
gcloud services enable run.googleapis.com artifactregistry.googleapis.com

# Un dépôt Docker dans la même région que le service
gcloud artifacts repositories create apps \
  --repository-format=docker --location=europe-west1
gcloud auth configure-docker europe-west1-docker.pkg.dev

L’image se publie ensuite comme vu dans B4, avec un tag immuable : europe-west1-docker.pkg.dev/atelier-notes-prod/apps/notes-api:1.4.0.

Le contrat du conteneur

La plateforme impose quelques règles simples :

  • l’application écoute sur le port fourni par la variable PORT (8080 par défaut) et sur 0.0.0.0, pas sur 127.0.0.1 ;
  • elle est sans état : un fichier écrit sur le disque local disparaît avec l’instance (on utilisera une base et un stockage objet) ;
  • elle démarre vite et s’arrête proprement à la réception de SIGTERM ;
  • elle écrit ses journaux sur la sortie standard.
// Node.js : respecter la variable PORT
const port = process.env.PORT || 8080;
app.listen(port, "0.0.0.0");

Déployer

gcloud run deploy notes-api \
  --image europe-west1-docker.pkg.dev/atelier-notes-prod/apps/notes-api:1.4.0 \
  --allow-unauthenticated \
  --memory 512Mi --cpu 1 \
  --concurrency 80 \
  --min-instances 0 --max-instances 5 \
  --set-env-vars NODE_ENV=production

La commande affiche l’URL HTTPS du service. --allow-unauthenticated rend l’API publique ; sans cette option, seuls les appelants authentifiés peuvent la joindre (utile pour un service interne).

gcloud run services describe notes-api --format='value(status.url)'
gcloud run revisions list --service notes-api

Mise à l’échelle et démarrage à froid

La plateforme ajoute des instances quand le nombre de requêtes simultanées dépasse la concurrence (80 requêtes par instance ici) et en retire quand le trafic baisse.

  • --min-instances 0 : aucune instance quand personne n’appelle, donc pas de coût de calcul au repos, mais la première requête attend le démarrage du conteneur (démarrage à froid).
  • --min-instances 1 : une instance reste chaude, la latence est stable, mais elle est facturée en continu.
  • --max-instances 5 : un plafond qui protège à la fois votre budget et votre base de données, qui n’accepte qu’un nombre limité de connexions.

Révisions, trafic et retour arrière

Chaque deploy crée une révision immuable (image + configuration). Pour une mise en production prudente, on déploie sans trafic, on teste, puis on bascule :

# 1. Nouvelle révision, 0 % du trafic, accessible par une URL étiquetée
gcloud run deploy notes-api --image .../notes-api:1.5.0 --no-traffic --tag candidate

# 2. Tester https://candidate---notes-api-xxxx.a.run.app, puis 10 % du trafic
gcloud run services update-traffic notes-api --to-tags candidate=10

# 3. Tout basculer sur la dernière révision
gcloud run services update-traffic notes-api --to-latest

# Retour arrière : toute la charge sur la révision précédente
gcloud run services update-traffic notes-api --to-revisions notes-api-00004-abc=100

Le retour arrière ne reconstruit rien : la révision précédente existe toujours et reçoit à nouveau le trafic en quelques secondes.

À retenir

Une image versionnée, le port lu dans PORT, une application sans état, des limites d’instances réfléchies et des révisions qui rendent chaque déploiement réversible.

Exercices

Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.

  1. TâcheDifficulté 12 indices

    Déployer l'image d'exemple et vérifier l'URL

    Dans un projet Google Cloud de test, déployez l’image publique d’exemple us-docker.pkg.dev/cloudrun/container/hello sous le nom hello en région europe-west1, accessible sans authentification. Récupérez ensuite l’URL avec gcloud run services describe hello --region europe-west1 --format='value(status.url)' puis exécutez curl -s -o /dev/null -w '%{http_code}' "$URL".

    • La commande `gcloud run deploy hello --image us-docker.pkg.dev/cloudrun/container/hello --region europe-west1 --allow-unauthenticated` se termine sans erreur
    • L'URL obtenue commence par `https://` et se termine par `.run.app`
    • La commande curl affiche exactement `200`
    • `gcloud run revisions list --service hello --region europe-west1` affiche une seule révision
  2. TâcheDifficulté 31 indice

    Déployer sans trafic puis revenir en arrière

    Sur le service hello, déployez une seconde révision avec la variable VERSION=2 sans lui envoyer de trafic et avec le tag candidate (--no-traffic --tag candidate --update-env-vars VERSION=2). Envoyez-lui 10 % du trafic, puis ramenez 100 % du trafic sur la première révision.

    • `gcloud run revisions list` affiche deux révisions
    • Après `update-traffic --to-tags candidate=10`, `gcloud run services describe hello --region europe-west1` indique 90 % / 10 %
    • Après `update-traffic --to-revisions <première révision>=100`, la première révision reçoit 100 % du trafic
    • Aucune image n'a été reconstruite
  3. QCMDifficulté 21 indice

    Démarrage à froid

    Une API interne n’est appelée que quelques fois par jour et ses utilisateurs acceptent une seconde d’attente. Quel réglage est le plus économique ?

    • --min-instances 2
    • --min-instances 0
    • --concurrency 1 et --min-instances 1

Quiz de fin de leçon

  1. Sur quel port l’application doit-elle écouter sur Cloud Run ?

    • Toujours 80
    • Le port fourni par la variable d'environnement PORT
    • N'importe quel port, la plateforme le détecte
  2. Qu’est-ce qu’une révision ?

    • Une copie de la base de données
    • Un instantané immuable de l'image et de la configuration d'un service
    • Un journal d'erreurs
  3. À quoi sert —max-instances ?

    • À accélérer le démarrage
    • À plafonner la montée en charge pour protéger le budget et les ressources en aval comme la base
    • À rendre le service public

La suite du cours

  1. Utiliser une base de données managée20 min
  2. Stocker des fichiers dans un stockage objet15 min
  3. Gérer les secrets et les identités15 min
  4. Surveiller : journaux, métriques et alertes20 min

Déployer une application sur le cloud · Intermédiaire · 1 h 30