Séparer la configuration
- Leçon 7
- 40 min
- Module 3 : Gérer les environnements et les secrets
Leçon 7 sur 15 · CI/CD, tests et mises en production sûresSéparer la configuration
1. Comprendre le chemin de livraison
2. Créer un pipeline CI reproductible
3. Gérer les environnements et les secrets
4. Mettre en production les changements d'IA et de base de données
5. Rétablir et maintenir le processus de mise en production
Ce que vous saurez faire
Exécutez l’image testée par CI dans deux endroits, la préproduction et la production, avec des paramètres différents. Ainsi, personne ne peut dire « ça fonctionnait en préproduction » à propos d’une autre construction.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- L’empreinte et la raison pour laquelle une étiquette peut changer, dans Registre et déploiement : Registre, dépôt et étiquette.
- Les paramètres à l’exécution et les fichiers de secrets, dans Configuration à l’exécution : une image, différents paramètres et Fichiers secrets.
- Les projets Compose et les volumes, dans Données persistantes : écrire compose.yaml.
- Comment CI construit l’image une seule fois et consigne son empreinte dans
build-info.json, dans Construire et tester : Construire une seule fois, puis conserver cette construction et Publier les preuves : build-info.json : empreinte, commit et exécution dans un seul fichier.
Ce qu’il vous faut sur votre ordinateur
- Votre dépôt public
github.com/<you>/ticket-api-ciavec.github/workflows/ci.yml, dans Publier les preuves : exercice guidé : conserver les preuves, et l’ensemble de règles surmain, dans Publier les preuves : protéger main avec un ensemble de règles. - Une exécution CI réussie sur
mainqui a publié une image dansghcr.io/<you>/ticket-api-ci, dans le même exercice guidé. Notez son empreinte à partir du fichierbuild-info.jsonde l’exécution. - Docker Desktop (ou Docker Engine sous Linux), dans Installer et vérifier : installer Docker du cours L’essentiel de Docker et du nuage pour les développeurs en IA.
- Parcours réel seulement : un abonnement Azure et Azure CLI avec l’extension
containerapp, comme dans Registre et déploiement : le parcours réel. Parcours simulé : rien de plus. - Si votre projet manque ou ne fonctionne plus, copiez l’instantané
end-of-m02, comme dans Utiliser un instantané. Un instantané ne peut pas contenir les paramètres GitHub : recréez l’ensemble de règles surmain.
Exécuté avec GitHub Actions (exécuteurs ubuntu-24.04) dans le dépôt public Nextia-Intelligence/ticket-api-ci, Docker Desktop 4.81.0 (Engine 29.6.1, Compose 5.2.0) sous macOS (Apple silicon) et Azure CLI 2.88.0 dans canadacentral. Les étapes pour Windows et Linux ne sont pas testées.
Deux parcours
Section intitulée « Deux parcours »Ce module propose deux parcours, comme dans le cours sur Docker. Choisissez-en un et utilisez-le dans les trois leçons. Vous pouvez aussi faire les deux.
| Réel | Simulé | |
|---|---|---|
| Où la préproduction et la production s’exécutent | Deux applications conteneurisées Azure, ticket-api-staging et ticket-api-production |
Deux projets Compose sur votre ordinateur, ticket-api-staging et ticket-api-production |
| Qui déploie | Le flux de travail Deploy (déployer) dans GitHub Actions | Vous, avec scripts/promote-local.sh |
| Coût | Pratiquement nul, si vous supprimez les ressources le jour même | Gratuit |
| Ce qu’il vous faut | Un abonnement Azure | Seulement Docker |
Chaque sortie porte une étiquette. Les sorties réelles proviennent des exécutions réelles dans Nextia-Intelligence/ticket-api-ci. Les sorties simulées proviennent de Docker sur un Mac, le même jour. Les ressources Azure de l’exécution de test n’existent plus. Leurs adresses ne répondent donc plus.
Une image, plusieurs environnements
Section intitulée « Une image, plusieurs environnements »L’exécution CI d’Amira sur main a construit une image et l’a testée. Son empreinte est sha256:4eb3db8d…. Le service de soutien veut essayer l’API avant que les clients y aient accès. L’équipe veut y activer /docs, pour que les testeurs puissent envoyer des requêtes dans le navigateur. La production doit masquer /docs.
Sam demande : « Est-ce que CI peut construire une deuxième image pour la préproduction, avec la documentation activée? » Amira dit non. Une deuxième construction est un deuxième artefact. Personne ne l’a testé. Personne ne peut prouver qu’il contient le même code et les mêmes paquets. Elle conserve donc un seul artefact (le résultat construit et testé du pipeline, ici l’image) et change seulement ses paramètres.
Un environnement est un endroit où l’application s’exécute, avec ses propres paramètres, secrets, accès et données. Ce cours en utilise deux :
- La préproduction est une copie de la production qui sert aux vérifications. L’équipe y essaie une nouvelle version avant que les utilisateurs la voient.
- La production est l’environnement que les utilisateurs et les autres systèmes appellent.
L’image en préproduction est une version candidate : une construction qui peut devenir la version publiée si toutes les vérifications réussissent. Quand elle arrive en production, rien ne change à l’intérieur. Seul l’environnement autour d’elle est différent.
| Doit être identique dans chaque environnement | Peut différer et doit rester à l’extérieur de l’image |
|---|---|
| Le code | Les paramètres : SHOW_DOCS, CLASSIFIER_VERSION, le nom de l’application, l’adresse |
Les paquets (requirements-run.txt) |
Les secrets : chaque environnement a sa propre clé d’API |
| L’image de base et le Dockerfile | L’identité qui la déploie et ce que cette identité peut modifier |
| L’empreinte de l’image | Le magasin de données : chaque environnement a sa propre base de données, ou aucune |
La règle est simple : si une différence figure dans la colonne de droite, placez-la dans un paramètre. Si quelqu’un veut une différence dans la colonne de gauche, c’est une nouvelle version. Elle passe de nouveau par CI.
Description textuelle du diagramme
L’empreinte en haut est la seule chose que les deux environnements partagent. Chaque colonne représente une limite. Les paramètres, la clé et l’identité de préproduction ne peuvent pas atteindre l’application de production, et inversement. La production a une règle de plus que la préproduction : une personne doit approuver avant le démarrage de sa tâche. Cette leçon crée les paramètres. Identifiants et accès crée les identités et les environnements GitHub. Promouvoir en préproduction déplace l’empreinte de gauche à droite.
Où se trouvent les paramètres
Section intitulée « Où se trouvent les paramètres »Les paramètres doivent se trouver ailleurs que dans l’image. Chaque parcours a son propre endroit pour les conserver.
Réel : l’application conteneurisée conserve ses paramètres et son secret. Vous les définissez à la création de l’application, et le pipeline change seulement l’image. Un déploiement avec az containerapp update --image conserve tous les autres paramètres de l’application.
Simulé : le projet contient un fichier de paramètres par environnement et un fichier de clé ignoré par Git par environnement :
# Settings of the local staging environment. No secrets here.ENVIRONMENT=stagingPORT=8081SHOW_DOCS=trueCLASSIFIER_VERSION=1.1# Settings of the local production environment. No secrets here.ENVIRONMENT=productionPORT=8082SHOW_DOCS=falseCLASSIFIER_VERSION=1.0Les fichiers de paramètres sont dans Git : ils ne contiennent aucun secret, et un réviseur doit voir chaque modification. Les clés sont dans secrets/staging_api_key.txt et secrets/production_api_key.txt, et secrets/ figure dans .gitignore. Le mot de passe de la base de données est dans .env, que Git ignore aussi.
CLASSIFIER_VERSION est là pour le module 4. La version 1.1.0 de l’API ne le lit pas encore. Vous voyez ce que cela signifie dans l’exemple détaillé.
Un fichier Compose décrit un seul environnement. Le nom de l’environnement vient du fichier de paramètres :
# One environment (staging or production) on your computer: the API and its# own database. The image is given by digest, so every# environment runs exactly the same build. Start it with scripts/promote-local.sh.name: ticket-api-${ENVIRONMENT:?Set ENVIRONMENT}
services: api: image: ${IMAGE:?Set IMAGE to the image name with its digest} ports: - "127.0.0.1:${PORT:?Set PORT}:8000" environment: API_KEY_FILE: /run/secrets/api_key REQUIRE_API_KEY: "true" DATABASE_URL: postgresql://tickets:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@db:5432/tickets SHOW_DOCS: ${SHOW_DOCS:-false} CLASSIFIER_VERSION: ${CLASSIFIER_VERSION:-1.0} secrets: - api_key healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=2)"] interval: 5s timeout: 3s retries: 5 depends_on: db: condition: service_healthy
db: image: postgres:18.6-trixie environment: POSTGRES_USER: tickets POSTGRES_DB: tickets POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - pgdata:/var/lib/postgresql healthcheck: test: ["CMD", "pg_isready", "-U", "tickets", "-d", "tickets"] interval: 2s timeout: 3s retries: 15
secrets: api_key: file: ../../secrets/${ENVIRONMENT}_api_key.txt
volumes: pgdata:Quatre lignes assurent la séparation :
| Ligne | Ce qu’elle fait |
|---|---|
name: ticket-api-${ENVIRONMENT…} |
Chaque environnement est un projet Compose distinct. Les noms de ses conteneurs, de son réseau et de ses volumes commencent par ticket-api-staging ou ticket-api-production. |
image: ${IMAGE…} |
L’image vient de l’extérieur, désignée par son empreinte. Le fichier n’a pas sa propre image. Il ne peut donc pas exécuter une autre construction par accident. |
file: ../../secrets/${ENVIRONMENT}_api_key.txt |
Chaque environnement lit sa propre clé. |
pgdata: |
Chaque projet obtient son propre volume. Chaque environnement a donc sa propre base de données. |
Avec :?, une valeur manquante devient une erreur, pas une chaîne vide. Si vous oubliez le fichier de paramètres, Compose s’arrête avec Set ENVIRONMENT (définir ENVIRONMENT), et rien ne démarre.
C’est le fichier de la demande de tirage nº 1 du dépôt de référence. Il a une lacune sur Apple silicon, que Promouvoir en préproduction montre et corrige.
Séparer les magasins de données
Section intitulée « Séparer les magasins de données »La préproduction et la production ne partagent jamais une base de données. Les billets de soutien d’un testeur en préproduction ne doivent pas apparaître dans l’historique de production. Une migration qui échoue en préproduction ne doit pas toucher les lignes de production. Pour cette raison, dans le module 4, chaque environnement exécute les migrations sur sa propre base de données.
- Simulé : chaque projet Compose a son propre conteneur PostgreSQL et son propre volume,
ticket-api-staging_pgdataetticket-api-production_pgdata. - Réel : le cours n’utilise aucune base de données dans le nuage, pour garder le coût à zéro. Les deux applications s’exécutent sans
DATABASE_URL. L’historique est donc désactivé, et/v1/historyrépond503comme prévu. Si vous ajoutez une base de données plus tard, donnez à chaque environnement son propre serveur ou sa propre base de données. Chacun doit aussi avoir son propre mot de passe.
Description textuelle du diagramme
Le parcours simulé conserve toutes les limites possibles sur un seul ordinateur. Chaque environnement a son propre projet, port, fichier de paramètres, clé et base de données. L’image a la même empreinte que dans le nuage. Ce qu’il ne peut pas simuler : les identités, l’adresse HTTPS et l’approbation par une autre personne. Dans la simulation, vous êtes le réviseur, et votre deuxième commande est l’approbation.
Exemple détaillé (réel) : deux applications, une image
Section intitulée « Exemple détaillé (réel) : deux applications, une image »Amira crée le groupe de ressources et l’environnement, comme dans le cours sur Docker, avec les noms du cours :
az group create --name rg-ticket-api-ci --location canadacentral --tags purpose=practice course=C19 -o tableaz containerapp env create --resource-group rg-ticket-api-ci --name cae-ticket-api-ci --location canadacentral -o tableLa sortie (réelle, abrégée) :
Location Name------------- ----------------canadacentral rg-ticket-api-ci
WARNING: No Log Analytics workspace provided.WARNING: Generating a Log Analytics workspace with name "workspace-rgticketapiciPwmn"Container Apps environment created. To deploy a container app, use: az containerapp create --help
Location Name ResourceGroup-------------- ----------------- ----------------Canada Central cae-ticket-api-ci rg-ticket-api-ciEnsuite, elle crée les deux applications à partir de la même image. Seuls --name, la clé et SHOW_DOCS diffèrent. L’image est désignée par l’empreinte de la première exécution CI réussie sur main (commit, modification enregistrée, c862935). Il n’y a pas de registre dans Azure : l’image est dans GitHub Container Registry. Le paquet est public, donc Azure le récupère sans mot de passe.
IMAGE=ghcr.io/usmanahmed99/ticket-api-ci@sha256:6c9bb4ed7c7cffc27f0c5489ba867d4d5db16def1c59c8bcbaeb3d26c45ce2e1STAGING_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(24))")az containerapp create --resource-group rg-ticket-api-ci --name ticket-api-staging --environment cae-ticket-api-ci \ --image "$IMAGE" --ingress external --target-port 8000 \ --cpu 0.25 --memory 0.5Gi --min-replicas 0 --max-replicas 2 \ --secrets api-key="$STAGING_KEY" \ --env-vars API_KEY=secretref:api-key REQUIRE_API_KEY=true SHOW_DOCS=true$IMAGE = "ghcr.io/usmanahmed99/ticket-api-ci@sha256:6c9bb4ed7c7cffc27f0c5489ba867d4d5db16def1c59c8bcbaeb3d26c45ce2e1"$STAGING_KEY = python -c "import secrets; print(secrets.token_urlsafe(24))"az containerapp create --resource-group rg-ticket-api-ci --name ticket-api-staging --environment cae-ticket-api-ci ` --image $IMAGE --ingress external --target-port 8000 ` --cpu 0.25 --memory 0.5Gi --min-replicas 0 --max-replicas 2 ` --secrets "api-key=$STAGING_KEY" ` --env-vars API_KEY=secretref:api-key REQUIRE_API_KEY=true SHOW_DOCS=trueUtilisez votre propre nom d’image et votre propre empreinte. La sortie (réelle, abrégée) :
Container app created. Access your app at https://ticket-api-staging.blackhill-8c0e6b69.canadacentral.azurecontainerapps.io/
Fqdn Revision------------------------------------------------------------------------- ---------------------------ticket-api-staging.blackhill-8c0e6b69.canadacentral.azurecontainerapps.io ticket-api-staging--cbaey1qPour la production, elle exécute la même commande avec trois changements : --name ticket-api-production, une nouvelle clé dans PRODUCTION_KEY et SHOW_DOCS=false. La sortie (réelle, abrégée) :
Container app created. Access your app at https://ticket-api-production.blackhill-8c0e6b69.canadacentral.azurecontainerapps.io/
Fqdn Revision---------------------------------------------------------------------------- ------------------------------ticket-api-production.blackhill-8c0e6b69.canadacentral.azurecontainerapps.io ticket-api-production--hx6e7q9Conservez les deux clés dans le terminal (ou dans un gestionnaire de mots de passe) jusqu’à Identifiants et accès. Là, chaque clé va dans son environnement GitHub sous le nom SMOKE_API_KEY. Ainsi, le test de bon fonctionnement du pipeline peut appeler l’application.
La preuve est arrivée plus tard dans la journée. Après la mise en production de la version 1.1.0, les deux applications exécutaient l’image ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d…. Le journal de déploiement de l’exécution 37665743749 montre la même ligne d’image dans les deux tâches (réel) :
staging / Deploy to staging | IMAGE: ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857aproduction / Deploy to production | IMAGE: ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857aEt /docs répondait 200 en préproduction et 404 en production (réel). Les mêmes octets, un comportement différent, à cause d’un seul paramètre.
Exemple détaillé (simulé) : comparer les deux environnements
Section intitulée « Exemple détaillé (simulé) : comparer les deux environnements »Avant de démarrer quoi que ce soit, Amira demande à Compose ce que chaque environnement exécuterait. docker compose config lit le fichier Compose et les fichiers de paramètres, puis affiche le résultat avec chaque variable remplacée. Il ne démarre rien.
export IMAGE=ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857adocker compose -f deploy/local/compose.yaml --env-file deploy/local/staging.env --env-file .env config > reports/staging-config.yamldocker compose -f deploy/local/compose.yaml --env-file deploy/local/production.env --env-file .env config > reports/production-config.yamldiff reports/staging-config.yaml reports/production-config.yaml$env:IMAGE = "ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857a"docker compose -f deploy/local/compose.yaml --env-file deploy/local/staging.env --env-file .env config > reports/staging-config.yamldocker compose -f deploy/local/compose.yaml --env-file deploy/local/production.env --env-file .env config > reports/production-config.yamlCompare-Object (Get-Content reports/staging-config.yaml) (Get-Content reports/production-config.yaml)Faites d’abord une prédiction : quelles lignes diff affichera-t-il? La ligne image: en fera-t-elle partie?
La sortie (simulée; chemins des fichiers de secrets abrégés) :
1c1< name: ticket-api-staging---> name: ticket-api-production10c10< CLASSIFIER_VERSION: "1.1"---> CLASSIFIER_VERSION: "1.0"13c13< SHOW_DOCS: "true"---> SHOW_DOCS: "false"30c30< published: "8081"---> published: "8082"61c61< name: ticket-api-staging_default---> name: ticket-api-production_default64c64< name: ticket-api-staging_pgdata---> name: ticket-api-production_pgdata67,68c67,68< name: ticket-api-staging_api_key< file: .../ticket-api-ci/secrets/staging_api_key.txt---> name: ticket-api-production_api_key> file: .../ticket-api-ci/secrets/production_api_key.txtChaque différence figure dans la colonne de droite du tableau : le nom, deux paramètres, le port, le réseau, le volume et la clé. La ligne image: n’est pas dans la liste, car elle est identique dans les deux fichiers :
image: ghcr.io/usmanahmed99/ticket-api-ci@sha256:4eb3db8d4ea249fb9b44b27d96deb68aba6da3e3fbc9cf32311a9cbadf4d857aVous pouvez répéter cette vérification avant chaque déploiement : comparez ce qui s’exécutera et cherchez une différence dans la colonne de gauche.
Plus tard, dans Promouvoir en préproduction, Amira démarre les deux projets et les appelle. Deux résultats comptent ici (simulé) :
/docsrépondait200sur le port 8081 et404sur le port 8082, comme dans le nuage.POST /v1/classifyavec « Package never arrived » (le colis n’est jamais arrivé) donnait{"category":"other","priority":3,"confidence":0.2,"model_version":"keywords-1.0"}dans les deux environnements, même si la préproduction aCLASSIFIER_VERSION=1.1.
Le deuxième résultat n’est pas une erreur de configuration. La version 1.1.0 du code ne lit pas CLASSIFIER_VERSION. Un paramètre que le code ignore ne change rien, et aucune erreur ne vous le signale. C’est pourquoi vous vérifiez un paramètre par son effet (ici /docs), et non par sa présence dans un fichier. Le module 4 ajoute le code qui lit ce paramètre. Les mêmes fichiers donnent alors keywords-1.1 en préproduction.
Exercice guidé : les fichiers d’environnement local
Section intitulée « Exercice guidé : les fichiers d’environnement local »Travaillez dans le dossier de votre projet, sur une nouvelle branche : git switch -c feature/deploy. Vous fusionnerez cette branche dans main par une demande de tirage (pull request) dans Promouvoir en préproduction : exercice guidé : promouvoir votre propre empreinte.
-
Créez le dossier
deploy/local, puis écrivezdeploy/local/compose.yaml,staging.envetproduction.envcomme ci-dessus. -
Si
.envn’existe pas, copiez.env.exampledans.env, puis changez le mot de passe qu’il contient. -
Créez les deux clés. Chacune est nouvelle et réservée à son environnement :
Terminal mkdir -p secrets reportspython3 -c "import secrets; print(secrets.token_urlsafe(24), end='')" > secrets/staging_api_key.txtpython3 -c "import secrets; print(secrets.token_urlsafe(24), end='')" > secrets/production_api_key.txtPowerShell (not tested) New-Item -ItemType Directory -Force secrets, reports | Out-Nullpython -c "import secrets; print(secrets.token_urlsafe(24), end='')" | Set-Content -NoNewline secrets/staging_api_key.txtpython -c "import secrets; print(secrets.token_urlsafe(24), end='')" | Set-Content -NoNewline secrets/production_api_key.txt -
Vérifiez que Git ne voit pas les clés :
git status --short. Résultat attendu : Git affichedeploy/, mais passecrets/,reports/ni.env. -
Réglez
IMAGEsur votre propre image avec l’empreinte debuild-info.json, comme dans l’exemple détaillé. -
Écrivez les deux configurations dans
reports/, puis comparez-les avecdiff(ouCompare-Object). -
Trouvez la ligne
image:dans les deux fichiers. Résultat attendu : la même empreinte, caractère pour caractère. -
Créez un commit (enregistrement des changements) des trois fichiers dans
deploy/local/:git add deploy/localetgit commit -m "Local staging and production environments".
Afficher le résultat attendu
diff indique seulement le nom du projet, CLASSIFIER_VERSION, SHOW_DOCS, le port (8081 et 8082), le réseau, le volume et le fichier de clé, comme dans l’exemple détaillé. Les deux fichiers ont la même ligne image: avec votre empreinte. git status --short affiche ?? deploy/ avant le commit, et rien sur secrets/, reports/ ou .env. Après l’étape 8, git log --oneline -1 affiche votre commit sur feature/deploy.
À vous de jouer : un troisième environnement
Section intitulée « À vous de jouer : un troisième environnement »Le responsable du centre de soutien demande un environnement de formation, training, où le nouveau personnel peut essayer l’API avec la documentation activée. Écrivez deploy/local/training.env avec PORT=8083. Ne changez pas compose.yaml.
Avant d’exécuter docker compose config avec le nouveau fichier, prédisez :
- le nom du projet,
- le nom de son volume,
- le fichier de clé dont il a besoin.
Exécutez ensuite la commande et vérifiez vos réponses. Que devez-vous créer d’autre avant que cet environnement puisse démarrer?
Afficher la réponse
ENVIRONMENT=training donne le projet ticket-api-training, le volume ticket-api-training_pgdata et le fichier de clé secrets/training_api_key.txt. Un test avec un troisième fichier a affiché les noms correspondants et published: "8083". docker compose config ne vérifie pas que le fichier de clé existe. Vous devez donc créer vous-même secrets/training_api_key.txt avec une nouvelle clé. Le nouvel environnement n’a exigé aucun changement au code, à l’image ou au fichier Compose : seulement un fichier de paramètres et une clé. C’est le signe d’une bonne séparation de la configuration.
Une deuxième construction pour la mise en production
Section intitulée « Une deuxième construction pour la mise en production »Erreur courante
L'étiquette qui a lancé une nouvelle construction
Symptôme : la première version de ci.yml dans le dépôt de référence s’exécutait aussi pour les étiquettes de version. Pousser l’étiquette v1.1.0 relançait tout le flux CI, et la tâche d’image construisait une nouvelle image pour l’étiquette. La préproduction avait vérifié l’image de l’exécution sur main, pas celle-ci. Rien dans le pipeline ne pouvait prouver que les deux constructions étaient identiques. Une image de base ou un paquet peut changer entre deux constructions.
Cause : le pipeline traitait « faire une mise en production » comme « construire ». C’est l’erreur la plus courante dans les pipelines de livraison : un nouvel artefact pour chaque environnement ou chaque étape.
Correction : une étiquette ne doit pas lancer de construction. La demande de tirage no 2 a supprimé le déclencheur d’étiquette de ci.yml :
push: branches: [main, "hotfix/**"] tags: ["v*"]et ajouté release.yml, qui attribue l’étiquette de version à l’image existante. L’exécution de test a mesuré le résultat : les étiquettes 1.1.0 et sha-92fff66 ont la même empreinte, sha256:4eb3db8d…. Promouvoir en préproduction présente le flux de travail.
Pour un vrai service d’IA : une image contient souvent un fichier de modèle ou en télécharge un pendant la construction. Une deuxième construction peut récupérer un modèle différent. Ses prédictions diffèrent alors de celles que la préproduction a vérifiées. Promouvez un seul artefact par son empreinte, et les prédictions en production seront celles que vous avez testées.
Vérifiez votre compréhension
Sam veut /docs en préproduction et demande au pipeline CI de construire une image de préproduction avec SHOW_DOCS réglé sur true à l'intérieur. Que répondez-vous, et que faites-vous plutôt?
Afficher la réponse
Une deuxième image est un deuxième artefact. Personne ne l’a testé, et personne ne peut prouver qu’il contient le même code et les mêmes paquets. Gardez une seule image et placez la différence dans un paramètre à l’extérieur de l’image : SHOW_DOCS=true en préproduction (la variable d’environnement de l’application conteneurisée, ou deploy/local/staging.env) et false en production. Les deux environnements exécutent alors la même empreinte. La vérification en préproduction porte donc sur la construction destinée à la production.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Prédisez : vous réglez CLASSIFIER_VERSION=1.1 dans staging.env et démarrez la version 1.1.0 de l'API. Quelle valeur de model_version la préproduction indique-t-elle, et pourquoi?
Afficher la réponse
keywords-1.0, comme en production. La version 1.1.0 du code ne lit pas CLASSIFIER_VERSION. Le paramètre n’a donc aucun effet, et rien ne signale d’erreur. Vérifiez un paramètre par son effet, par exemple /docs (200 en préproduction, 404 en production), pas par sa présence dans un fichier. Ce paramètre fonctionne à partir de la version qui le lit (module 4).
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Nommez deux éléments qui doivent être identiques en préproduction et en production, et deux qui doivent différer. Pourquoi le stockage des données doit-il différer?
Afficher la réponse
Identiques : l’empreinte de l’image et le code (ainsi que les paquets et le Dockerfile, qui sont dans l’image). Différents : les paramètres (comme SHOW_DOCS) et les secrets (la clé propre à chaque environnement), ainsi que l’identité et le stockage des données. Le stockage des données doit différer pour que les données de test de préproduction n’apparaissent jamais en production. De plus, une migration ou une erreur en préproduction ne peut alors pas modifier les enregistrements de production.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Un artefact, plusieurs environnements : la préproduction et la production exécutent la même empreinte d’image. Seuls les paramètres, les secrets, les identités et le stockage des données diffèrent.
- En service : chaque application conteneurisée contient ses propres paramètres et son secret. En simulation :
deploy/local/<environment>.envetsecrets/<environment>_api_key.txt, que Git ignore. - Un seul fichier Compose avec
name: ticket-api-${ENVIRONMENT}donne à chaque environnement son propre projet, port, clé et base de données. docker compose configetdiffmontrent les différences avant toute exécution. La ligneimage:doit être identique.- Vérifiez un paramètre par son effet. La version 1.1.0 ignore
CLASSIFIER_VERSION. - Une mise en production ne doit pas relancer la construction : une étiquette qui déclenche une deuxième construction crée un artefact que personne n’a testé.
Les applications existent, mais personne ne peut encore y déployer sans votre propre connexion à Azure. La prochaine leçon donne à chaque environnement une identité sans mot de passe qui peut modifier seulement sa propre application.
Leçon suivante : Identifiants et accès