Введение
Файл, удалённый из образа контейнера, может по-прежнему существовать в более раннем слое образа. Правила игнорирования Git также не управляют тем, что Docker получает при сборке.
Вы исследуете подготовленный образ, ограничите его входные данные сборки и проверите каждый слой нового образа. Обработчик и порядок работы с Docker продолжают предыдущую лабораторную работу. Все учётные данные — вымышленные локальные тестовые значения; кэшированная база и вспомогательные средства проверки подготовлены.
Проверьте подготовленные входные данные сборки
На этом шаге вы отделите правила игнорирования системы контроля версий от входных данных сборки Docker.
cd /home/labex/project/ticket-image
ls -a
ls -a включает файлы, начинающиеся с точки. Этот проект содержит обработчик, публичную конфигурацию, входной/выходной каталоги, private.env и debug.txt. Последние два — приватные локальные входные файлы, а не файлы для передачи.
cat .gitignore
Git игнорирует два приватных имени. Это влияет на отслеживание файлов в Git, а не на контекст сборки Docker.
cat .dockerignore
Сейчас файл пуст. .dockerignore управляет тем, какие пути Docker исключает при получении контекста сборки. Файл может игнорироваться Git и всё равно отправляться в сборку Docker.
cat Dockerfile
COPY . /app/ копирует весь доступный контекст. Последующий RUN rm ... удаляет приватные файлы из итоговой файловой системы, но не отменяет более ранний слой образа.
Найдите скрытую копию в слое
На этом шаге вы сравните итоговую файловую систему с сохранёнными слоями образа.
Подготовленный старый тег ticket-image:legacy был собран по этому Dockerfile. Запустите одноразовый контейнер проверки. --rm автоматически удаляет этот временный контейнер после завершения ls; его команда переопределяет стандартный запуск обработчика образа:
sudo docker run --rm ticket-image:legacy ls -a /app
Итоговый /app не должен показывать private.env или debug.txt. Он по-прежнему содержит обработчик и публичную конфигурацию.
docker history показывает инструкции сборки образа. --no-trunc сохраняет полный текст инструкций:
sudo docker history --no-trunc ticket-image:legacy
Найдите широкое копирование, за которым следует удаление. История объясняет последовательность, но не содержимое каждого файла. Подготовленное вспомогательное средство course-image-scan сохраняет этот реальный образ и читает каждый сохранённый слой и конфигурацию образа:
sudo course-image-scan ticket-image:legacy
Ожидаются находки с именами приватных файлов в более раннем слое и целевыми учебными учётными данными со скрытым значением. Код завершения 1 означает находки; 2 или CHECK ERROR означает, что проверка не удалась. Фиксированная область этого средства — перечисленные приватные имена и эти вымышленные учётные данные, а не полноценное сканирование секретов рабочей среды.
Удаления в последующих слоях не стирают более ранние байты. Поэтому успешного ls итоговой файловой системы недостаточно.
Исключите приватные входные данные сборки
На этом шаге вы сохраните локальные приватные файлы, исключив их из контекста Docker.
nano .dockerignore
Используйте этот полный файл:
private.env
debug.txt
input/
output/
Каждая строка — путь или каталог для исключения. Эти шаблоны убирают приватную конфигурацию, отладочные материалы и данные времени выполнения из входных данных сборки; обработчик и config.public остаются доступны.
Сохраните с помощью Ctrl+O, Enter и выйдите с помощью Ctrl+X. Не удаляйте локальные приватные файлы. Игнорирование пути должно ограничивать его включение, а не уничтожать локальную конфигурацию.
Ограничьте область копирования Dockerfile
На этом шаге вы явно зададите необходимые входные файлы образа.
Старая инструкция удаления теперь не нужна и завершилась бы ошибкой, поскольку исключённые файлы недоступны. Откройте Dockerfile:
nano Dockerfile
Используйте этот полный файл:
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/ перечисляет только два необходимых бизнес-файла. Сохраните USER nobody и исходную команду запуска из предыдущей лабораторной работы. Сохраните с помощью Ctrl+O, Enter, Ctrl+X.
Два механизма работают вместе: .dockerignore ограничивает доступные входные данные сборки, а явный COPY ограничивает содержимое этого образа. Ни один не полагается на удаление секрета после его попадания в слой.
Соберите и проверьте новый артефакт
На этом шаге вы проверите заново собранный образ для передачи, не меняя смысл прежних свидетельств.
sudo docker build -t ticket-image:delivery .
Ожидается успешная локальная сборка. Новый тег отличается от ticket-image:legacy.
sudo course-image-scan ticket-image:delivery
Ожидается PASS для каждого сохранённого слоя и конфигурации образа. Этот результат для конкретной цели не утверждает, что обнаружены все возможные секреты или уязвимости.
Теперь независимо проверьте контекст:
sudo course-context-check .
Это подготовленное средство собирает временный образ с фиксированной проверкой COPY ., применяет ту же реальную проверку слоёв, затем удаляет временный образ. Ожидается PASS. Это показывает, что приватные файлы исключены из контекста, а не просто пропущены более узким COPY вашего образа для передачи.
Старый образ всё ещё может содержать исходную находку. Пересборка чистого артефакта для передачи не переписывает ранее распространённые образы и не отзывает утёкшие учётные данные. Реальное раскрытие требует изученного ранее процесса замены учётных данных и надлежащей очистки старых копий. Здесь целевой токен намеренно вымышлен, а приёмка касается нового образа для передачи.
Запустите исходный отчёт из нового образа
На этом шаге вы докажете, что удаление приватных входных данных сборки сохранило необходимые файлы и поведение обработчика.
Выходной каталог уже принадлежит UID 65534 с закрытым доступом для записи. Снова используйте непривилегированный обработчик и порядок работы с привязками каталогов из предыдущей лабораторной работы:
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
Ожидается 65534.
sudo docker logs ticket-image-worker
Ожидаются mode=report и tickets=2. Первая строка берётся из необходимой публичной конфигурации; вторая — результат чтения исходных входных данных и записи реального отчёта.
sudo docker exec ticket-image-worker cat /data/output/report.txt
Ожидается tickets=2. У обработчика по-прежнему есть вход только для чтения и выход с возможностью записи, а приватная конфигурация внутри образа не нужна.
Подтвердите локальные исходники и результат передачи
На этом шаге вы завершите работу, сохранив и локальные приватные входные файлы, и безопасный артефакт для передачи.
Перечислите приватные исходные файлы, не выводя их содержимое:
ls -l private.env debug.txt
Оба должны по-прежнему существовать локально. Их удаление обошло бы задуманное упражнение по границе сборки.
sudo course-image-scan ticket-image:delivery
sudo docker ps
Сканирование образа для передачи должно пройти, а ticket-image-worker должен работать. Проверка курса также исследует реальный контекст сборки, проверяет идентификатор работающего образа и исходный отчёт. Отдельный письменный файл исследования сдавать не нужно.
Резюме
Вы ограничили реальные входные данные сборки Docker, скопировали только необходимые бизнес-файлы, проверили все сохранённые слои и конфигурацию образа и сохранили исходный непривилегированный обработчик. Одна чистая итоговая файловая система не установила бы эту границу.



