Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
FROM scratch в Dockerfile
Что это такое?
FROM scratch — это специальный базовый образ в Docker, который представляет собой пустой контейнер без какой-либо операционной системы, утилит или библиотек. Когда вы используете FROM scratch, Docker начинает с абсолютно ничего и добавляет только те файлы, которые вы явно копируете.
Это означает, что финальный образ будет содержать только то, что вам действительно нужно для запуска приложения — ничего больше, ничего меньше.
Зачем нужно?
Преимущества:
- Минимальный размер образа — самый маленький возможный контейнер
- Безопасность — нет лишних утилит, значит нет лишних уязвимостей
- Производительность — быстрее скачивается и развёртывается
- Чистота — только необходимые компоненты
Пример 1: Go приложение
Для статически скомпилированного бинарика (Go, Rust):
# Этап сборки
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
RUN go build -o app .
# Финальный образ
FROM scratch
COPY --from=builder /app/app .
EXPOSE 8080
CMD ["./app"]
Такой образ будет размером всего несколько МБ.
Пример 2: Python приложение (более сложно)
Для Python это сложнее, так как нужна сама Python runtime. Но для микросервисов можно использовать:
# Многоэтапная сборка
FROM python:3.11-slim as builder
WORKDIR /app
# Установка зависимостей
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM scratch
# Копируем Python из builder стадии
COPY --from=builder /usr/local/bin/python3 /usr/local/bin/
COPY --from=builder /usr/local/lib/python3.11 /usr/local/lib/
# Копируем наше приложение
COPY --from=builder /root/.local /root/.local
COPY . /app
WORKDIR /app
ENV PATH=/root/.local/bin:$PATH
CMD ["python3", "app.py"]
Пример 3: Статический контент (веб-сервер)
Для простого статического веб-сервера:
FROM scratch
ADD index.html /index.html
EXPOSE 80
CMD ["/server"] # Скопированный веб-сервер
Альтернативы FROM scratch
FROM alpine:latest Для случаев, когда нужны некоторые утилиты:
FROM alpine:latest
RUN apk add --no-cache python3
COPY app.py .
CMD ["python3", "app.py"]
Размер: ~7 МБ (vs scratch — ничего)
FROM distroless Образы от Google, содержащие только минимум ОС:
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
FROM gcr.io/distroless/python3.11
COPY --from=0 /app /app
COPY --from=0 /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
WORKDIR /app
CMD ["main.py"]
Практический пример: Node.js приложение
# Сборка
FROM node:20-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# FROM scratch требует ручной сборки бинарника
# Проще использовать alpine
FROM alpine:latest
RUN apk add --no-cache nodejs
COPY --from=builder /app /app
WORKDIR /app
EXPOSE 3000
CMD ["node", "server.js"]
Когда использовать FROM scratch
✓ Используйте, когда:
- Приложение статически скомпилировано (Go, Rust)
- Нужно минимизировать размер образа
- Критична безопасность (нет лишнего кода)
- Внутренние микросервисы, не требующие отладки
✗ Не используйте, когда:
- Приложение требует интерпретатор (Python, Ruby, PHP без компиляции)
- Нужны стандартные утилиты (ls, cat, curl) для отладки
- Требуется shell для скрипта в ENTRYPOINT
- Нужны динамические библиотеки (libc, openssl)
Практические советы
1. Используйте многоэтапную сборку (multi-stage builds)
# Сборка в одном контейнере
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# Финальный контейнер минимальный
FROM scratch
COPY --from=builder /app/myapp /
EXPOSE 8080
CMD ["/myapp"]
2. Для статической сборки Python используйте PyInstaller
FROM python:3.11-slim as builder
RUN pip install pyinstaller
COPY app.py .
RUN pyinstaller --onefile app.py
FROM scratch
COPY --from=builder /dist/app /app
CMD ["/app"]
3. Проверяйте размер образов
# Узнать размер образа
docker image ls | grep my-image
# Анализ слоёв
docker history my-image:latest
4. Если нужна отладка, используйте distroless вместо scratch
Scratch не содержит даже bash, поэтому отладка невозможна:
# Это не сработает!
docker run -it my-image /bin/bash
Сравнение размеров
| Базовый образ | Размер | Случай использования |
|---|---|---|
| scratch | ~0 МБ | Статически скомпилированные приложения |
| alpine | ~5 МБ | Легкие контейнеры с утилитами |
| distroless | ~20 МБ | Python/Node приложения без отладки |
| ubuntu | ~70+ МБ | Приложения, требующие стандартных утилит |
| python:3.11 | ~900 МБ | Разработка с полным Python |
Вывод
FROM scratch — это мощный инструмент для создания минимальных и безопасных Docker образов. Он идеален для статически скомпилированных приложений, но для динамических языков (Python, Node.js) обычно требует предварительной компиляции или использования distroless образов. Правильный выбор базового образа — важный аспект оптимизации контейнеризированных приложений.