Гид по технологиям

Как восстановить Dockerfile из образа Docker

8 min read DevOps Обновлено 01 Dec 2025
Восстановление Dockerfile из образа
Восстановление Dockerfile из образа

Схема слоев Docker-образа

Быстрые ссылки

  • Цель

  • Команда docker history

  • Автоматизация извлечения слоёв с помощью Whaler и Dfimage

  • Ограничения

  • Резюме

Цель

Когда вы создаёте образы Docker самостоятельно, храните Dockerfile под версионным контролем рядом с кодом. Так вы всегда сможете восстановить точную историю сборки.

Но что делать, если Dockerfile недоступен — например, образ из публичного реестра, закрытый репозиторий или снимок, не привязанный к версии? В таких случаях полезно иметь методику, позволяющую получить воспроизводимый Dockerfile прямо из образа, который уже есть на машине. Docker не хранит исходный Dockerfile внутри образа, но историю слоёв и команды, которые создавали слои, — да. На основе этой информации можно собрать приближённую копию Dockerfile.

Важно: реконструированный Dockerfile — это реконструкция, а не гарантированная точная копия оригинала.

Команда docker history

Команда docker history показывает историю слоёв образа и команду, которая создала каждый слой. Это отправная точка для восстановления Dockerfile.

Пример исходного простого Dockerfile для Node.js:

FROM node:16
COPY app.js .
RUN app.js --init
CMD ["app.js"]

Построим образ:

$ docker build -t node-app:latest .

Посмотрим историю слоёв:

$ docker history node-app:latest

Пример упрощённого вывода (таблица):

IMAGE CREATED CREATED BY SIZE COMMENT c06fc21a8eed 8 seconds ago /bin/sh -c #(nop) CMD [“app.js”] 0B 74d58e07103b 8 seconds ago /bin/sh -c ./app.js –init 0B 22ea63ef9389 19 seconds ago /bin/sh -c #(nop) COPY file:… 50B 424bc28f998d 4 days ago /bin/sh -c #(nop) CMD [“node”] 0B

4 days ago /bin/sh -c #(nop) ENTRYPOINT ... 0B... По умолчанию Docker усекaет длинные команды. Чтобы увидеть полные команды, используйте формат и флаг `--no-trunc`: ``` $ docker history node-app:latest --format "{{.CreatedBy}}" --no-trunc ``` Вы получите список, похожий на: ``` /bin/sh -c #(nop) CMD ["app.js"] /bin/sh -c ./app.js --init /bin/sh -c #(nop) COPY file:0c0828d0765af4dd... in . /bin/sh -c #(nop) CMD ["node"] /bin/sh -c #(nop) ENTRYPOINT ["docker-entrypoint.sh"] ... ``` Из этого списка видно, какие инструкции Docker интерпретировал как `COPY`, `RUN`, `CMD`, `ENTRYPOINT` и т.д. Для простых образов этого может быть достаточно, чтобы вручную воспроизвести Dockerfile. Совет: используйте `--no-trunc` и форматирование, чтобы получить читаемый вывод, и фильтруйте лишние базовые слои, если знаете базовый образ. ## Автоматизация извлечения слоёв с помощью Whaler и Dfimage Ручной разбор вывода `docker history` утомителен и подвержен ошибкам. Существуют утилиты, которые автоматизируют процесс и формируют Dockerfile по истории слоёв. Одна из таких — Whaler, объединённая в образ `alpine/dfimage`. Запустите `dfimage`, передав тег образа. Контейнеру потребуется доступ к Docker сокету хоста, чтобы он мог просмотреть список образов и при необходимости подтянуть образ. Пример запуска: ``` $ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine/dfimage node-app:latest ``` Пример вывода анализа: ``` Analyzing node-app:latest Docker Version: 20.10.13 GraphDriver: overlay2 Environment Variables |PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |NODE_VERSION=16.14.2 |YARN_VERSION=1.22.18 Image user |User is root Dockerfile: ... ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node"] COPY file:bcbc3d5784a8f10... in . app.js RUN ./app.js --init CMD ["app.js"] ``` `dfimage` генерирует Dockerfile, который воспроизводит переход от пустой FS (`scratch`) до последнего слоя образа, включая слои базового образа. В результате вы получите последовательность инструкций, которые при повторной сборке дадут похожий образ. Полезные альтернативы/дополнения: - dive — интерактивный анализатор слоёв и содержимого образа (помогает понять, какие файлы добавлены в каждый слой). - skopeo — позволяет просматривать метаданные образа без необходимости докачивать большой образ локально. - docker save + tar — распаковка образа для исследования содержимого слоёв вручную. ## Практические приёмы для работы с копиями и содержимым образа Иногда `docker history` показывает, что произошёл `COPY`, но не указывает исходный путь. В таких случаях можно извлечь файл из образа и проанализировать его: 1. Создайте контейнер без запуска: ``` $ docker create --name tmp node-app:latest ``` 2. Скопируйте файл из контейнера на хост: ``` $ docker cp tmp:/app/app.js ./recovered-app.js ``` 3. Просмотрите содержимое и признаки исходного файла (заголовок, комментарии, метаданные внутри кода). 4. Удалите временный контейнер: ``` $ docker rm tmp ``` Этот подход помогает подобрать осмысленный путь-источник для инструкции `COPY` в реконструируемом Dockerfile. ## Ограничения Реконструкция Dockerfile из образа — полезный приём, но не волшебство. Основные ограничения: - Не все инструкции оставляют след в слое. Инструкции, которые не изменили файловую систему (например, некоторые `ENV`, `LABEL` или пустые `RUN`), могут вообще не появиться в истории. - `COPY` и `ADD` теряют исходный путь: история содержит лишь ссылку на хеш файла из build-context. Вы не узнаете оригинальный путь в хосте. - Мультистадийные сборки усложняют соответствие между финальным образом и промежуточными Dockerfile-инструкциями. Если не знать исходный базовый образ и этапы, восстановить точный многослойный Dockerfile сложно. - Скук (squashed) образы или образы, в которых слои были объединены/оптимизированы, теряют промежуточную информацию. - Хакерские приёмы в Dockerfile (скрипты, которые меняют метаданные, динамическая загрузка) невозможно восстановить полностью. Важно: никогда не полагайтесь на автоматически сгенерированный Dockerfile без его ручной проверки и тестирования. ## Когда метод не сработает - Исходный образ — минимизированный, где команды были объединены или удалены после оптимизации. - Образ создан с помощью нестандартных билд-систем (например, сборка через custom toolchain, не использующая обычные инструкции Docker). - Исходные файлы были встроены в бинарные артефакты: по содержимому невозможно понять путь и контекст. ## Альтернативные подходы Если автоматическая реконструкция недостаточна, рассмотрите: - Поиск в репозиториях и реестрах: иногда Dockerfile хранится рядом с образом в registry/description или на GitHub/GitLab. - Обратная разработка содержимого образа: извлеките бинарные артефакты и сопроводительную документацию, чтобы составить Dockerfile с нуля. - Обращение к автору образа: запросите оригинальный Dockerfile или инструкции по сборке. - Использование инструментов для статического анализа образа (`dive`, `trivy` для проверки уязвимостей) и восстановления зависимостей. ## Мини-методология для восстановления Dockerfile (шаг за шагом) 1. Скопируйте образ локально: `docker pull `. 2. Изучите историю: `docker history --no-trunc --format '{{.CreatedBy}}' `. 3. Сгенерируйте Dockerfile через `alpine/dfimage` или аналог: `docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine/dfimage `. 4. Инспектируйте содержимое образа: `docker run --rm -it --entrypoint sh ` или создайте контейнер и используйте `docker cp` для извлечения файлов. 5. Сравните с предполагаемым базовым образом и при необходимости добавьте `FROM ` в начало. 6. Проверьте Dockerfile, соберите локально и прогоните тесты: `docker build -t reconstructed:latest .`. 7. Запустите тестовые сценарии и проверьте соответствие поведения оригинального образа. ## Критерии приёмки - Сборка проходит без ошибок и создаёт образ, запускающийся как оригинал. - Ключевые файлы и бинарники совпадают по содержимому или поведению. - Сервис стартует и проходит smoke-тесты (например, отвечает на HTTP-запросы, возвращает ожидаемый код состояния). - Размер образа находится в разумном диапазоне относительно оригинала (большие отличия могут сигнализировать о проблемах). ## Рольовые чек-листы Developer - Извлечь слои и посмотреть `docker history`. - Найти и извлечь конфигурационные файлы и скрипты. - Попробовать собрать образ локально и запустить unit/integration тесты. Security Engineer - Просканировать исходный и реконструированный образы на уязвимости (trivy, clair). - Проверить права пользователей и наличие секретов в слоях. Release Manager - Сопоставить теги образов и версии зависимостей. - Убедиться, что Dockerfile размещён под версионным контролем после восстановления. ## Чек-лист команд и шпаргалка - Просмотр истории: `docker history --no-trunc ` - Полный формат: `docker history --format "{{.CreatedBy}}" --no-trunc ` - Генерация через dfimage: `docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine/dfimage ` - Просмотр файлов: `docker create --name tmp `; `docker cp tmp:/path/file ./`; `docker rm tmp` - Интерактивный анализ: `dive ` - Экспорт образа: `docker save -o image.tar` и распаковка `tar -xf image.tar` ## Критические рекомендации и безопасность Важно: при подключении Docker сокета в контейнер вы даёте ему привилегированный доступ к Docker демону. Используйте образы с доверенным кодом и по возможности выполняйте анализ в изолированном CI-окружении. Проверяйте, чтобы восстановленный Dockerfile не содержал секретов и чувствительных данных, которые могли оказаться включены в слои. ## Короткая шпаргалка по работе с COPY и ADD - Если история показывает `COPY file: in /app`, извлеките файл из образа и посмотрите, какие зависимости он требует. - Подумайте, откуда логично брать этот файл в исходном коде (например, `src/app.js` или `dist/app.js`). - Для восстановления используйте осмысленные пути в build-контексте и документируйте предположения. ## Примеры ошибок и когда ожидать ручной работы - Многоступенчатая сборка: нужно определить, какие артефакты были перенесены между стадиями. - Скрипты в RUN выполняли сетевые загрузки: вы увидите только результат, но не саму команду в точности, если она не изменила FS заметно. ## 1‑строчный глоссарий - Слой — инкремент файловой системы, созданный инструкцией Dockerfile. - Build context — набор файлов и директорий, которые доступны при выполнении `docker build`. - Squash — объединение слоёв в один пол для уменьшения размера. ## Часто задаваемые вопросы ### Можно ли гарантированно восстановить точный оригинальный Dockerfile? Нет. Можно получить точную последовательность слоёв и команды, которые создали видимые изменения, но исходные пути для COPY/ADD и некоторые незаметные инструкции утрачиваются. ### Помогает ли `docker inspect`? Да. `docker inspect` показывает метаданные образа — теги, переменные окружения, точки входа, CMD. Это полезно для восстановления метаданных Dockerfile. ### Как минимум тестировать реконструированный образ? Соберите образ и прогоните smoke- и integration-тесты. Сравните поведение сервиса и, при необходимости, контейнерные показатели. ## Резюме Реконструкция Dockerfile возможна и часто даёт достаточно точный результат для практических задач: дебага, миграции, воспроизведения среды. Команда `docker history` — базовый инструмент; `alpine/dfimage`, `dive` и ручная работа с контейнером и файлами помогают автоматизировать и дополнять вывод. Всегда проверяйте и тестируйте результат: некоторые инструкции восстановить невозможно, особенно связанные с исходными путями для `COPY/ADD`, мультистадийными сборками и командами без изменения FS. Важно: не используйте автоматическую реконструкцию как единственный источник правды — храните Dockerfile в системе контроля версий и документируйте процесс сборки. --- Социальные превью OG title: Восстановление Dockerfile из образа OG description: Как по слоям образа восстановить Dockerfile: команды, инструменты и ограничения. Практичные шаги и чек-листы. Короткое объявление (для рассылки, 100–200 слов): Нужен Dockerfile, но он утерян? В этой статье показаны практические способы восстановить Dockerfile из существующего образа Docker. Вы узнаете, как использовать `docker history` и инструменты вроде `alpine/dfimage` и `dive`, как извлечь файлы из образа и как проверить реконструированный Dockerfile. Также рассмотрены ограничения метода и чек-листы для разработчиков, security-инженеров и релиз-менеджеров. Статья поможет быстро получить воспроизводимый Dockerfile и избежать проблем при миграции или отладке образов.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Скачать и установить appx/appxbundle/msixbundle
Windows

Скачать и установить appx/appxbundle/msixbundle

Кнопка «Установить» в Microsoft Store не отображается
Windows

Кнопка «Установить» в Microsoft Store не отображается

Полноэкранный режим в Windows 10 — как включить
Windows

Полноэкранный режим в Windows 10 — как включить

Восстановление приложений на iPhone и iPad
Мобильные устройства

Восстановление приложений на iPhone и iPad

Как редактировать полученное письмо в Outlook
Outlook

Как редактировать полученное письмо в Outlook

Отключить Global Menu в Ubuntu 13.10
Ubuntu

Отключить Global Menu в Ubuntu 13.10