Introduction
Un fichier supprimé d'une image de conteneur peut toujours exister dans une couche précédente de l'image. Les règles d'exclusion Git ne contrôlent pas non plus ce que Docker reçoit pendant une construction.
Vous étudierez une image préparée, restreindrez ses entrées de construction et vérifierez chaque couche d'une nouvelle image. Le worker et la méthode Docker reprennent le lab précédent. Tous les identifiants sont des données de test locales fictives ; la base en cache et les utilitaires d'inspection sont préparés.
Inspecter les entrées de construction préparées
Dans cette étape, vous distinguerez les règles d'exclusion du suivi de versions des entrées de construction Docker.
cd /home/labex/project/ticket-image
ls -a
ls -a inclut les fichiers dont le nom commence par un point. Ce projet contient le worker, une configuration publique, des répertoires d'entrée/sortie, private.env et debug.txt. Ces deux derniers sont des entrées locales privées, pas des fichiers à livrer.
cat .gitignore
Git ignore les deux noms privés. Cela affecte le suivi par Git, pas le contexte de construction de Docker.
cat .dockerignore
Le fichier est actuellement vide. .dockerignore contrôle les chemins exclus par Docker lorsqu'il reçoit le contexte de construction. Un fichier peut être ignoré par Git tout en étant envoyé à une construction Docker.
cat Dockerfile
COPY . /app/ copie tout le contexte disponible. Le RUN rm ... ultérieur supprime les fichiers privés du système de fichiers final, mais cela n'annule pas la couche d'image précédente.
Repérer la copie cachée dans une couche
Dans cette étape, vous comparerez le système de fichiers final aux couches d'image enregistrées.
Le tag hérité préparé ticket-image:legacy a été construit à partir de ce Dockerfile. Lancez un conteneur d'inspection ponctuel. --rm supprime automatiquement ce conteneur temporaire après la fin de ls ; sa commande remplace le démarrage par défaut du worker de l'image :
sudo docker run --rm ticket-image:legacy ls -a /app
Le répertoire /app final ne doit pas lister private.env ni debug.txt. Il contient toujours le worker et la configuration publique.
docker history affiche les instructions de construction de l'image. --no-trunc conserve le texte complet des instructions :
sudo docker history --no-trunc ticket-image:legacy
Repérez la copie large suivie de la suppression. L'historique explique la séquence, mais pas le contenu de chaque fichier. L'utilitaire préparé course-image-scan enregistre cette véritable image et lit chaque couche enregistrée ainsi que la configuration de l'image :
sudo course-image-scan ticket-image:legacy
Des détections nommant les fichiers privés dans une couche précédente et un identifiant d'exercice ciblé à valeur masquée sont attendues. Le code de sortie 1 signifie qu'il y a des détections ; 2 ou CHECK ERROR signifie que l'inspection a échoué. Le périmètre fixe de l'utilitaire comprend ces noms privés et cet identifiant fictif ; ce n'est pas un scanner complet de secrets de production.
Les suppressions dans les couches ultérieures n'effacent pas les octets précédents. Un ls satisfaisant sur le système de fichiers final est donc insuffisant.
Exclure les entrées de construction privées
Dans cette étape, vous conserverez les fichiers privés locaux tout en les excluant du contexte Docker.
nano .dockerignore
Utilisez ce fichier complet :
private.env
debug.txt
input/
output/
Chaque ligne est un chemin ou un répertoire à exclure. Ces motifs retirent la configuration privée, les éléments de débogage et les données d'exécution des entrées de construction ; le worker et config.public restent disponibles.
Enregistrez avec Ctrl+O, Enter, puis quittez avec Ctrl+X. Ne supprimez pas les fichiers privés locaux. Ignorer un chemin doit limiter son inclusion, pas détruire la configuration locale.
Limiter le périmètre de copie du Dockerfile
Dans cette étape, vous rendrez explicites les entrées nécessaires à l'image.
L'ancienne instruction de suppression est maintenant inutile et échouerait, car les fichiers exclus ne sont plus disponibles. Ouvrez le Dockerfile :
nano Dockerfile
Utilisez ce fichier complet :
FROM desklite-base:1.37.0
WORKDIR /app
COPY worker.sh config.public /app/
USER nobody
CMD ["sh", "/app/worker.sh"]
COPY worker.sh config.public /app/ liste uniquement les deux fichiers métier nécessaires. Conservez USER nobody et la commande de démarrage d'origine du lab précédent. Enregistrez avec Ctrl+O, Enter, Ctrl+X.
Les deux contrôles fonctionnent ensemble : .dockerignore restreint les entrées de construction disponibles, et le COPY explicite restreint ce que cette image inclut. Aucun des deux ne repose sur la suppression d'un secret après son entrée dans une couche.
Construire et inspecter le nouvel artefact
Dans cette étape, vous inspecterez une image de livraison nouvellement construite au lieu de changer la signification des anciennes preuves.
sudo docker build -t ticket-image:delivery .
Une construction locale réussie est attendue. Le nouveau tag est distinct de ticket-image:legacy.
sudo course-image-scan ticket-image:delivery
Un PASS pour chaque couche enregistrée et pour la configuration de l'image est attendu. Ce résultat limité aux cibles définies ne prétend pas avoir détecté tous les secrets ou toutes les vulnérabilités possibles.
Vérifiez maintenant le contexte indépendamment :
sudo course-context-check .
Cet utilitaire préparé construit une image temporaire avec une sonde COPY . fixe, applique la même inspection réelle des couches, puis supprime cette image temporaire. Le résultat attendu est PASS. Cela démontre que les fichiers privés ont été exclus du contexte, au lieu d'être simplement omis par votre COPY de livraison plus restreint.
L'image héritée peut toujours contenir la détection d'origine. Reconstruire un artefact de livraison propre ne réécrit pas les images déjà distribuées et ne révoque pas les identifiants divulgués. Une exposition réelle nécessite le processus de remplacement des identifiants appris précédemment et un nettoyage approprié des anciennes copies. Ici, le jeton ciblé est délibérément fictif, et l'acceptation concerne la nouvelle image de livraison.
Exécuter le rapport d'origine depuis la nouvelle image
Dans cette étape, vous prouverez que retirer les entrées de construction privées a préservé les fichiers et le comportement nécessaires au worker.
Le répertoire de sortie appartient déjà à l'UID 65534 avec un accès privé en écriture. Réutilisez le worker non root et la méthode de montage bind du lab précédent :
sudo docker run -d --name ticket-image-worker --network none --mount type=bind,src=/home/labex/project/ticket-image/input,dst=/data/input,readonly --mount type=bind,src=/home/labex/project/ticket-image/output,dst=/data/output ticket-image:delivery
sudo docker exec ticket-image-worker id -u
Le résultat attendu est 65534.
sudo docker logs ticket-image-worker
Les messages attendus sont mode=report et tickets=2. La première ligne provient de la configuration publique nécessaire ; la seconde provient de la lecture de l'entrée d'origine et de l'écriture du véritable rapport.
sudo docker exec ticket-image-worker cat /data/output/report.txt
Le résultat attendu est tickets=2. Le worker conserve une entrée en lecture seule et une sortie accessible en écriture, sans avoir besoin de configuration privée dans l'image.
Confirmer les sources locales et les preuves de livraison
Dans cette étape, vous terminerez en conservant à la fois les entrées privées locales et l'artefact de livraison sûr.
Listez les fichiers sources privés sans afficher leur contenu :
ls -l private.env debug.txt
Les deux doivent toujours exister localement. Les supprimer contournerait l'exercice prévu sur la limite de construction.
sudo course-image-scan ticket-image:delivery
sudo docker ps
L'analyse de livraison doit réussir et ticket-image-worker doit être en cours d'exécution. La vérification du cours teste aussi le contexte de construction réel, vérifie l'ID de l'image en cours d'exécution et contrôle le rapport d'origine. Aucun fichier d'investigation écrit séparé n'est à remettre.
Résumé
Vous avez restreint les entrées réelles de construction Docker, copié uniquement les fichiers métier nécessaires, inspecté toutes les couches enregistrées et la configuration de l'image, et préservé le worker non root d'origine. Un système de fichiers final propre n'aurait pas suffi à établir cette limite.



