Ответ
Инструкция FROM scratch в Dockerfile указывает на создание образа с абсолютно пустой файловой системой. Это специальный, минимально возможный базовый образ, который не содержит никаких файлов, библиотек, утилит или даже стандартных директорий, таких как /bin или /lib.
Преимущества использования
- Минимальный размер: Образ содержит только ваше приложение и его зависимости, что значительно уменьшает его размер, ускоряя загрузку, передачу и развертывание.
- Повышенная безопасность: Отсутствие shell-оболочки, системных утилит и библиотек резко сокращает поверхность атаки на контейнер.
Основные сценарии использования
- Статически скомпилированные приложения: Идеально подходит для приложений, написанных на Go, Rust или C++, которые компилируются в один бинарный файл без внешних зависимостей.
- Создание собственных базовых образов: Используется как отправная точка для построения кастомных базовых образов с нуля.
Пример для Go-приложения
# Этап 1: Сборка приложения
FROM golang:1.19 as builder
WORKDIR /app
COPY . .
# Собираем статически скомпилированный бинарник
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .
# Этап 2: Создание минимального образа
FROM scratch
# Копируем только скомпилированный файл из сборщика
COPY --from=builder /app/myapp .
# Запускаем приложение
CMD ["/myapp"]
Ключевые особенности
- В образе отсутствует shell (
/bin/sh), поэтому инструкцииRUN,CMDиENTRYPOINTдолжны использоватьexec-форму в виде JSON-массива (например,CMD ["/myapp", "--arg"]). - Нет никаких стандартных утилит (
ls,cat) или пакетных менеджеров (apt,apk).
Ответ 18+ 🔞
Да ты посмотри, что творят, блядь! Вот эта самая FROM scratch в Dockerfile — это ж просто пиздец какой минимализм, в рот меня чих-пых! Это не образ, а чистое, блядь, ничто. Пустота. Как твоя голова после пятницы.
Представь: нет там ни /bin, ни /lib, ни одной ёбаной библиотеки. Никакого шелла, чтобы покомандовать, никакого ls, чтобы посмотреть, что натворил. Абсолютный ноль, вакуум, блядь. Создали образ — и там только твоё приложение торчит, как хуй в проруби.
И зачем это, спрашивается, нахуй?
А вот зачем, умник:
- Размер, блядь! Образ получается овердохуища маленький. Не 700 мегабайт с кучей хлама, а ровно столько, сколько весит твой бинарник. Качает, разворачивает — всё мгновенно.
- Безопасность, ёпта! Атаковать нечего, блядь! Нет шелла — не зайти. Нет лишних утилит — не сломать. Контейнер как танк, только внутри один стрелок сидит.
Кому это впизду нужно?
В основном, конечно, всяким гоферам, растам и прочим цэплюсникам. У них приложение компилируется в один жирный бинарник, который сам по себе, как слон, и ему от системы нихуя не надо. Вот его и суют в этот scratch.
Смотри, как это выглядит на практике, блядь:
# Этап первый: собираем всё, как обычно
FROM golang:1.19 as builder
WORKDIR /app
COPY . .
# Компилим так, чтобы бинарник был самодостаточный, блядь
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .
# Этап второй: магия начинается
FROM scratch
# Берём из предыдущего этапа только готовый бинарник
COPY --from=builder /app/myapp .
# И запускаем его
CMD ["/myapp"]
Видишь? Из первого, навороченного образа мы вытащили только готовый myapp и положили его в пустоту. Всё, пиздец. Образ готов.
Но есть нюанс, ёбаный в рот!
Там же нет шелла, блядь! Поэтому команды CMD и ENTRYPOINT обязательно пиши в JSON-формате, вот так: CMD ["/myapp", "--arg"]. Если напишешь как строку CMD /myapp, Docker попытается вызвать /bin/sh -c, а его-то как раз и нету! И контейнер твой нахуй сломается при старте.
И да, если приложению вдруг понадобится что-то прочитать из файла или, не дай бог, TLS-сертификаты — их тоже надо явно в образ скопировать. Потому что там нихуя нет, даже корневых сертификатов, блядь.
Короче, инструмент для гиков, которые помешаны на размере и безопасности. Красиво, но без башенки не лезь — обосрёшься.