Travail final
- Après le module 5
- environ 2 h
Ce que vous saurez faire
Transférez l’API de billets de soutien à une autre équipe comme le ferait un professionnel. Tout le monde doit pouvoir construire la même image avec vos fichiers et déterminer de quel commit (modification enregistrée) elle provient. Elle doit démarrer avec le bon port et les bonnes vérifications de santé, sans contenir de secret. Son déploiement et sa suppression doivent être consignés et vérifiés. Vous apportez une petite modification au projet, puis vous fournissez des preuves pour chacun de ces points.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Vous avez terminé les modules 1 à 5. Chaque partie ci-dessous nomme les leçons qu’elle utilise.
Ce qu’il vous faut sur votre ordinateur
- Votre projet
ticket-apiavecDEPLOY.md, dans son état à la fin de Vérifier et supprimer : Exercices du module. deploy/containerapp.yaml, tiré de Configuration opérationnelle : les paramètres dans un seul fichier.deploy/local-cloud.yaml, tiré de Registre et déploiement : le parcours simulé : les mêmes étapes sur votre ordinateur.- Le projet dans un dépôt Git, comme dans Créer et déployer votre première API. Sinon, exécutez
git init, puis enregistrez tous les fichiers dans un commit. Vérifiez d’abord que.gitignorecontient.envetsecrets/. - Docker, installé dans Installer et vérifier : installer Docker.
- Pour le parcours réel de la partie 4 : un abonnement Azure et l’interface en ligne de commande Azure. Vous les avez configurés dans Registre et déploiement : avant l’étape 1 : se connecter et préparer l’abonnement. Sans eux, utilisez le parcours simulé. Les deux parcours permettent de terminer le cours.
- Si votre projet manque ou ne fonctionne plus, copiez l’instantané
end-of-m05. Utiliser un instantané présente les étapes. Un instantané n’a ni.env, nisecrets/, ni ressources infonuagiques : recréez-les.
Testé avec Docker Desktop 4.81.0 (Docker Engine 29.6.1) sur macOS, avec une puce Apple. Les étapes Azure ont été exécutées le même jour avec Azure CLI 2.88.0 et l’extension containerapp 1.3.0b5, dans la région canadacentral. Les étapes Windows et Linux n’ont pas été testées.
La situation
Section intitulée « La situation »L’équipe de plateforme du service de soutien exploitera désormais l’API de billets. Avant de l’accepter, elle demande quatre choses :
- Une image reproductible et traçable. L’équipe construit l’image avec vos fichiers et obtient les mêmes paquets. Chaque image indique sa version et le commit Git dont elle provient.
- Des ports et des vérifications de santé corrects. L’API est accessible uniquement là où elle doit l’être. Une vérification de santé indique si le processus fonctionne. Une panne de base de données rend l’API « non prête », mais ne la redémarre pas.
- Aucun secret dans l’image. Aucune clé ni aucun mot de passe dans les couches, les paramètres de l’image, Git ou le fichier Compose.
- Un déploiement et un nettoyage que quelqu’un d’autre peut répéter. Une liste de vérification, un inventaire de toutes les ressources et la preuve qu’il ne reste rien.
Règles pour chaque partie
Section intitulée « Règles pour chaque partie »- Créez un fichier
evidence.mdà l’extérieur du dossier du projet, par exemple~/projects/c18-evidence.md. Après chaque partie, copiez-y les commandes et les sorties demandées. - Ne copiez jamais une clé ou un mot de passe dans les preuves. Lorsqu’une vérification utilise un secret, montrez seulement le résultat (par exemple, un compte de
0). - Utilisez un nouveau dossier pour la construction de la partie 1. Une construction qui fonctionne seulement dans votre dossier habituel n’est pas reproductible.
Partie 1 : une image reproductible et traçable
Section intitulée « Partie 1 : une image reproductible et traçable »Utilise L’essentiel du Dockerfile : créer requirements-run.txt dans un conteneur et Construire efficacement : le cache des couches.
L’équipe de plateforme veut que chaque image contienne des étiquettes : des métadonnées clé-valeur dans la configuration de l’image. L’Open Container Initiative définit leurs noms standards. Vous définissez les valeurs pendant la construction avec des arguments de construction (ARG) : des valeurs qui existent seulement pendant la construction de l’image.
-
Ajoutez ces lignes au
Dockerfile. Décidez où les placer. Un nouveau commit changeREVISION, et ce changement ne doit pas relancerpip install.ARG VERSION=devARG REVISION=unknownLABEL org.opencontainers.image.title="ticket-api" \org.opencontainers.image.version="${VERSION}" \org.opencontainers.image.revision="${REVISION}" -
Enregistrez la modification dans un commit. Copiez ensuite le projet dans un nouveau dossier avec Git, sans aucun fichier ignoré :
Fenêtre de terminal cd ~/projectsgit clone ticket-api ticket-api-freshcd ticket-api-fresh -
Construisez l’image avec la version et l’identifiant court du commit :
Fenêtre de terminal docker build --build-arg VERSION=1.1.0 --build-arg REVISION=$(git rev-parse --short HEAD) -t ticket-api:1.1.0 .Dans PowerShell, utilisez
--build-arg REVISION=$(git rev-parse --short HEAD)de la même façon. Cela fonctionne aussi dans PowerShell. -
Affichez les étiquettes :
Fenêtre de terminal docker image inspect ticket-api:1.1.0 --format '{{json .Config.Labels}}' -
Prouvez que l’image contient exactement les paquets de
requirements-run.txt:Fenêtre de terminal docker run --rm ticket-api:1.1.0 pip freeze > installed.txtdiff installed.txt requirements-run.txt && echo "same packages"Sur Windows, utilisez
Compare-Object (Get-Content installed.txt) (Get-Content requirements-run.txt). L’absence de sortie signifie qu’il n’y a aucune différence. -
Faites un autre commit dans votre dossier de projet habituel (une modification de
README.mdsuffit). Récupérez-le dans le nouveau dossier avecgit pull, puis reconstruisez l’image avec le nouvel identifiant de commit. Regardez quelles étapes indiquentCACHED(en cache).
Preuves pour la partie 1 : l’emplacement des nouvelles lignes dans le Dockerfile, avec une phrase pour expliquer votre choix; la sortie des étiquettes; le résultat de diff; la liste des étapes en cache à l’étape 6.
Ce que vous devriez voir
La sortie des étiquettes contient vos valeurs, par exemple :
{"org.opencontainers.image.revision":"1b1b958","org.opencontainers.image.title":"ticket-api","org.opencontainers.image.version":"1.1.0"}diff n’affiche rien, puis la sortie indique same packages (mêmes paquets). Lorsque les lignes ARG et LABEL suivent USER app, les sept étapes numérotées ([1/7] à [7/7]) indiquent CACHED à l’étape 6 : seules les étiquettes changent. Si vous placez ARG REVISION près du début, avant RUN pip install, un nouveau commit relance pip install. Un argument de construction accessible à une étape fait partie de la clé de cache de cette étape.
Partie 2 : ports et santé
Section intitulée « Partie 2 : ports et santé »Utilise Ports et accès au service : choisir qui peut se connecter, Données persistantes : À vous de jouer : la base de données s’arrête et Configuration opérationnelle : trois sondes, deux points de terminaison.
-
Ajoutez une vérification de santé au service
apidanscompose.yaml. L’image allégée n’a pas curl, alors utilisez Python :healthcheck:test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=2)"]interval: 10stimeout: 3sretries: 3start_period: 5s -
Fournissez les arguments de construction à Compose pour que
docker compose up --buildajoute aussi les étiquettes à l’image. Remplacezbuild: .par :build:context: .args:VERSION: 1.1.0REVISION: ${REVISION:-unknown} -
Démarrez l’API et la base de données. Attendez environ 15 secondes, puis affichez l’état :
Fenêtre de terminal REVISION=$(git rev-parse --short HEAD) docker compose up -d --builddocker compose psDans PowerShell :
$env:REVISION = git rev-parse --short HEAD, puisdocker compose up -d --build. -
Affichez qui peut se connecter :
docker compose port api 8000. -
Arrêtez la base de données. Vérifiez
/readyet/health. Attendez 30 secondes et exécutez de nouveaudocker compose ps. -
Redémarrez la base de données et vérifiez
/ready. -
Ouvrez
deploy/containerapp.yaml. Vérifiez que chaque sonde utilise le bon chemin et le bon port. Notez pourquoi chaque sonde utilise son chemin.
Preuves pour la partie 2 : les sorties de docker compose ps avant et après l’étape 5; les codes d’état de /ready et /health à l’étape 5; la sortie de l’étape 4 avec une phrase expliquant qui peut se connecter et pourquoi; vos notes de l’étape 7.
Ce que vous devriez voir
Les deux services indiquent Up … (healthy) (en cours d’exécution et en bonne santé). docker compose port api 8000 donne 127.0.0.1:8000 : seuls les programmes sur votre ordinateur peuvent se connecter. Quand la base de données est arrêtée, /ready donne 503 et /health donne 200. Après 30 secondes, api indique toujours (healthy) (en bonne santé) : la vérification de santé utilise /health. Une panne de base de données ne marque donc pas l’API comme défectueuse et ne la redémarre pas. C’est correct : un redémarrage ne peut pas réparer une base de données. /ready indique à la plateforme de ne pas envoyer de trafic à cette réplique. Dans deploy/containerapp.yaml, les sondes de démarrage et de vitalité utilisent /health, et la sonde de disponibilité utilise /ready. Elles utilisent toutes le port 8000, où l’application écoute dans le conteneur.
Partie 3 : aucun secret nulle part
Section intitulée « Partie 3 : aucun secret nulle part »Utilise Sécurité à l’exécution : garder les identifiants secrets hors de l’image, Configuration à l’exécution : fichiers secrets et Identité et secrets : où conserver le secret.
Vérifiez cinq endroits. Pour chaque vérification, consignez la commande et son résultat. Ne consignez jamais le secret lui-même. Les commandes macOS et Linux lisent la clé dans une variable pour qu’elle n’apparaisse pas à l’écran.
-
Lisez la clé et le mot de passe dans des variables :
Fenêtre de terminal KEY=$(cat secrets/api_key.txt)PW=$(grep POSTGRES_PASSWORD .env | cut -d= -f2) -
L’historique de l’image (chaque instruction, au complet) :
Fenêtre de terminal docker history --no-trunc ticket-api:1.1.0 | grep -c -e "$KEY" -e "$PW" -
La configuration de l’image (valeurs d’environnement, étiquettes, commande) :
Fenêtre de terminal docker image inspect ticket-api:1.1.0 | grep -c -e "$KEY" -e "$PW" -
Chaque fichier dans chaque couche. Enregistrez l’image dans un fichier, puis faites une recherche dedans :
Fenêtre de terminal docker save ticket-api:1.1.0 -o /tmp/ticket-api.tarmkdir -p /tmp/ticket-api-layers && tar -xf /tmp/ticket-api.tar -C /tmp/ticket-api-layersfor f in $(find /tmp/ticket-api-layers -type f); do tar -xOf "$f" 2>/dev/null || cat "$f"; done | grep -a -c -e "$KEY" -e "$PW"rm -rf /tmp/ticket-api.tar /tmp/ticket-api-layers -
Git :
git ls-files .env secretsn’affiche rien, etgit check-ignore .env secrets/api_key.txtaffiche les deux noms. -
Le fichier Compose :
grep -c -e "$KEY" -e "$PW" compose.yaml.
Les commandes des étapes 2 à 4 et 6 fonctionnent dans un terminal Bash ou zsh. Sur Windows, exécutez-les dans WSL, ou faites les mêmes vérifications avec Select-String dans PowerShell. Les étapes Windows n’ont pas été testées.
Preuves pour la partie 3 : les cinq résultats et, pour chaque endroit, une phrase expliquant pourquoi un projet négligé pourrait y contenir un secret.
Ce que vous devriez voir
Chaque compte vaut 0. git ls-files n’affiche rien. git check-ignore affiche .env et secrets/api_key.txt. Voici pourquoi chaque endroit compte : docker history montre toutes les valeurs de RUN, ENV et ARG; docker image inspect montre les valeurs de ENV et les étiquettes; un fichier copié puis supprimé reste dans une couche inférieure; un fichier .env enregistré dans un commit reste dans l’historique Git même après sa suppression; un mot de passe saisi dans compose.yaml se retrouve dans Git avec ce fichier. Si un compte n’est pas 0, ne vous contentez pas de supprimer le secret : il est exposé. Créez une nouvelle clé ou un nouveau mot de passe, et remplacez-le partout où il est utilisé.
Partie 4 : déployer, vérifier et supprimer
Section intitulée « Partie 4 : déployer, vérifier et supprimer »Utilise Registre et déploiement : construire pour le processeur du nuage et Configuration opérationnelle : les paramètres dans un seul fichier. Cette partie utilise aussi Vérifier et supprimer : tests de bon fonctionnement : ce que ce déploiement doit prouver, Nettoyer à partir d’un inventaire explicite et Connaître les coûts : un inventaire des ressources.
Choisissez un parcours. Indiquez réel ou simulé dans vos preuves.
- Avant de créer quoi que ce soit, écrivez l’inventaire dans
DEPLOY.md: chaque ressource prévue, son coût possible et sa méthode de suppression. - Construisez l’image pour
linux/amd64avec les étiquettes de la partie 1, puis poussez-la avec l’étiquette1.1.0. - Créez ou mettez à jour l’application conteneurisée avec
deploy/containerapp.yaml: la clé comme secret,REQUIRE_API_KEY=true,SHOW_DOCS=false, les sondes et au plus 2 répliques. - Exécutez les tests de bon fonctionnement :
/health,/ready, une classification avec la clé, la même requête sans la clé,/docsethttp://au lieu dehttps://. - Affichez les étiquettes de l’image dans le registre :
docker buildx imagetools inspect <registry>.azurecr.io/ticket-api:1.1.0 --format '{{json .Image.Config.Labels}}'. Comparezrevision(révision) à votre commit. - Supprimez le groupe de ressources. Attendez que
az group existsindiquefalse(faux). Si vous avez créé un Key Vault, purgez-le. Exécutez ensuite les vérifications de votre liste de nettoyage.
- Écrivez dans
DEPLOY.mdl’inventaire de la conception réelle, comme si vous alliez la déployer : chaque ressource, son coût possible et sa méthode de suppression. - Construisez l’image avec les étiquettes de la partie 1. Construisez-la aussi pour
linux/amd64avecdocker buildx build --platform linux/amd64, pour prouver que la plateforme du nuage fonctionne. Vous n’avez pas besoin de la pousser. - Démarrez la simulation avec
docker compose -f deploy/local-cloud.yaml up -d. - Exécutez les tests de bon fonctionnement sur
http://127.0.0.1:8080:/health,/ready, une classification avec la clé, la même requête sans la clé et/docs. - Affichez les étiquettes de l’image du conteneur en cours d’exécution avec
docker inspect. - Arrêtez et supprimez tout ce que vous avez créé pour cette partie. Vérifiez avec
docker ps -a,docker image lsetdocker volume ls.
Preuves pour la partie 4 : l’inventaire; les résultats des tests de bon fonctionnement (codes d’état et corps, sans la clé); l’étiquette de révision de l’image déployée ou en cours d’exécution; le compte rendu du nettoyage, avec les commandes et les sorties prouvant qu’il ne reste rien.
Ce que vous devriez voir
Tests de bon fonctionnement : /health → {"status":"ok"} (état correct), /ready → {"status":"ready"} (prêt), classification avec la clé → 200, sans la clé → 401, /docs → 404. Parcours réel seulement : http:// → 301 vers https://. La première requête peut prendre environ 18 secondes si l’application était à zéro réplique. L’inventaire contient le groupe de ressources et ses cinq ressources (registre, identité, espace de travail Log Analytics, environnement Container Apps, application conteneurisée). Il contient aussi le Key Vault, si vous en avez créé un. Le nettoyage réel se termine par az group exists --name rg-ticket-api-practice → false, et az keyvault list-deleted sans votre coffre. Le nettoyage simulé se termine sans conteneur ticket-api-cloud-sim dans docker ps -a.
Vérifiez votre travail
Section intitulée « Vérifiez votre travail »Ce cours n’a pas encore de personne responsable de la révision. Examinez vos preuves avec ce tableau, ou demandez à un collègue de l’utiliser. Marquez chaque élément comme démontré, partiellement démontré ou pas encore démontré, avec une raison. Le cours est terminé quand chaque élément est démontré. Vous pouvez améliorer un élément et le réexaminer aussi souvent que nécessaire.
| Preuves requises | Démontré quand |
|---|---|
| Construction reproductible du conteneur | La construction à partir d’un nouveau clone fonctionne; pip freeze dans l’image correspond à requirements-run.txt; les étiquettes montrent la version et le commit; un nouveau commit réutilise la couche pip install. |
| Configuration correcte du port et de la santé | Le port de l’hôte est lié à 127.0.0.1 localement; la vérification de santé indique healthy (en bonne santé); une base de données arrêtée donne /ready 503, tandis que /health reste à 200 et que le conteneur ne redémarre pas; les sondes dans deploy/containerapp.yaml utilisent les bons chemins et le bon port. |
| Aucun secret intégré | Les cinq vérifications donnent 0 ou rien; Git ignore .env et secrets/; la clé atteint l’application uniquement à l’exécution (fichier de secret localement, secret de plateforme dans le nuage). |
| Liste de vérification du déploiement et du nettoyage | DEPLOY.md contient l’inventaire avec les coûts, les étapes de déploiement et les étapes de nettoyage; les tests de bon fonctionnement réussissent, y compris les cas d’échec (401, 404); des commandes vérifient le nettoyage, sans le présumer. |
Le bon fonctionnement du cas normal ne suffit pas. L’API répond peut-être 200 sans clé, un secret apparaît dans une couche, ou une ressource reste après le nettoyage. L’élément est alors pas encore démontré, même si tout le reste fonctionne.
Erreur courante
Les étiquettes indiquent unknown
Symptôme : docker image inspect affiche "org.opencontainers.image.revision":"unknown" (révision inconnue) après docker compose up --build.
Cause : Compose lit ${REVISION:-unknown} depuis votre interpréteur de commandes ou .env. Vous n’avez pas défini REVISION avant la commande, alors Compose a utilisé la valeur par défaut.
Solution : définissez-la dans la même commande : REVISION=$(git rev-parse --short HEAD) docker compose up -d --build. Pour une vraie mise en production, un pipeline de construction la définit chaque fois pour éviter les oublis. Le cours CI/CD, tests et mises en production sûres le fait.
Récapitulatif
- Une étiquette et un argument de construction permettent de relier une image à une version et à un commit. Placez-les vers la fin du Dockerfile pour que le cache continue de fonctionner.
/healthrépond à « le processus est-il actif? » et/readyà « peut-il traiter des requêtes maintenant? ». Une panne de base de données change seulement la deuxième réponse.- Cherchez les secrets à cinq endroits : l’historique, la configuration, les couches, Git et le fichier Compose.
- Un déploiement est terminé seulement quand son nettoyage est vérifié.
Ensuite : CI/CD, tests et mises en production sûres construit, teste et promeut cette image automatiquement. Son pipeline comprend chaque vérification de ce travail.