Aller au contenu
English

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 mainEnviron 120 minutes

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

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.

L’équipe de plateforme du service de soutien exploitera désormais l’API de billets. Avant de l’accepter, elle demande quatre choses :

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  • 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.

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.

  1. Ajoutez ces lignes au Dockerfile. Décidez où les placer. Un nouveau commit change REVISION, et ce changement ne doit pas relancer pip install.

    ARG VERSION=dev
    ARG REVISION=unknown
    LABEL org.opencontainers.image.title="ticket-api" \
    org.opencontainers.image.version="${VERSION}" \
    org.opencontainers.image.revision="${REVISION}"
  2. 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 ~/projects
    git clone ticket-api ticket-api-fresh
    cd ticket-api-fresh
  3. 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.

  4. Affichez les étiquettes :

    Fenêtre de terminal
    docker image inspect ticket-api:1.1.0 --format '{{json .Config.Labels}}'
  5. 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.txt
    diff 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.

  6. Faites un autre commit dans votre dossier de projet habituel (une modification de README.md suffit). Récupérez-le dans le nouveau dossier avec git pull, puis reconstruisez l’image avec le nouvel identifiant de commit. Regardez quelles étapes indiquent CACHED (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.

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.

  1. Ajoutez une vérification de santé au service api dans compose.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: 10s
    timeout: 3s
    retries: 3
    start_period: 5s
  2. Fournissez les arguments de construction à Compose pour que docker compose up --build ajoute aussi les étiquettes à l’image. Remplacez build: . par :

    build:
    context: .
    args:
    VERSION: 1.1.0
    REVISION: ${REVISION:-unknown}
  3. 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 --build
    docker compose ps

    Dans PowerShell : $env:REVISION = git rev-parse --short HEAD, puis docker compose up -d --build.

  4. Affichez qui peut se connecter : docker compose port api 8000.

  5. Arrêtez la base de données. Vérifiez /ready et /health. Attendez 30 secondes et exécutez de nouveau docker compose ps.

  6. Redémarrez la base de données et vérifiez /ready.

  7. 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.

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.

  1. 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)
  2. 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"
  3. 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"
  4. 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.tar
    mkdir -p /tmp/ticket-api-layers && tar -xf /tmp/ticket-api.tar -C /tmp/ticket-api-layers
    for 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
  5. Git : git ls-files .env secrets n’affiche rien, et git check-ignore .env secrets/api_key.txt affiche les deux noms.

  6. 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é.

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.

  1. 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.
  2. Construisez l’image pour linux/amd64 avec les étiquettes de la partie 1, puis poussez-la avec l’étiquette 1.1.0.
  3. 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.
  4. Exécutez les tests de bon fonctionnement : /health, /ready, une classification avec la clé, la même requête sans la clé, /docs et http:// au lieu de https://.
  5. 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}}'. Comparez revision (révision) à votre commit.
  6. Supprimez le groupe de ressources. Attendez que az group exists indique false (faux). Si vous avez créé un Key Vault, purgez-le. Exécutez ensuite les vérifications de votre liste de nettoyage.

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.

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.
  • /health ré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.